![]() |
Array of TJepeg in Blob schreiben und lesen
Ich möchte meine alte Datenbanklösung zur speicherung von Bildern erneuern und auf den neuesten Stand bringen.
Bisher habe ich die Bilder auf die Platte geschrieben und von dort dann in ein Blob-Feld geschrieben (LoadFromFile). Das ist natürlich recht langsam. Meine Bildfolgen (Video) habe ich in eine Zip-Datei gepackt und dann in das Blob-Feld geschrieben. Funktioniert zwar, ist aber langsam. Die Datenbank ist eine AbsoluteDatabase, soll eventuell auf Firebird umgestellt werden. Nun will ich das ganze mal neu aufbauen und mit Streams im Speicher arbeiten. Mit einzelnen Bildern habe ich das bisher auch gut hinbekommen. Hier ein Beispiel:
Code:
Falls jemand dazu Verbesserungsvorschläge hat bitte melden, habe erst seit kurzem mit Streams angefangen.
// **************************************************************************
// * Bild oder Bildfolge aus Datenbank lesen und in Image schreiben * // ************************************************************************** procedure TDM.BildAnzeigen(ID: Integer); var BlobStream: TStream; PicJpg: TJPEGImage; JpegArray :Array[0..39] of TJpegImage; begin qData.SQL.Text := 'Select * From Bilder Where ID = :ID'; qData.ParamByName('ID').AsInteger := ID; qData.Open; // Bild einlesen und in Image schreiben if (AktData.Typ = 'B') then begin try PicJpg := TJPEGImage.Create; // Bild aus Datenbank lesen und in Stream schreiben BlobStream := qData.CreateBlobStream(qData.FieldByName('PicData'), bmRead); BlobStream.Position := 0; // JPEG lesen und der ImageBox zuweisen PicJpg.LoadFromStream(BlobStream); frmMain.img.Picture.Assign(PicJpg); frmMain.lblBGroese.Caption := 'Größe: ' + frmMain.img.Picture.Width.ToString + 'x' + frmMain.img.Picture.Height.ToString; frmMain.lblQualitaet.Caption := 'Aufnahme Qualität: ' + Config.Kompression.ToString; finally BlobStream.Free; PicJpg.Free; end; uSubs.StatusBarChange(1); end; // Video einlesen und in Image schreiben if (AktData.Typ = 'V') then begin try // Bild aus Datenbank lesen und in Stream schreiben BlobStream := qData.CreateBlobStream(qData.FieldByName('PicData'), bmRead); BlobStream.Position := 0; // JPEGArray lesen und der ImageBox zuweisen JpegArray[0].LoadFromStream(BlobStream); frmMain.img.Picture.Assign(JpegArray[0]); // Hier Fehler frmMain.lblBGroese.Caption := 'Größe: ' + frmMain.img.Picture.Width.ToString + 'x' + frmMain.img.Picture.Height.ToString; frmMain.lblQualitaet.Caption := 'Aufnahme Qualität: ' + Config.Kompression.ToString; finally BlobStream.Free; PicJpg.Free; end; uSubs.StatusBarChange(1); end; qData.Close; end; Meine alte Datenbank möchte ich gerne umstellen und die Zip-Dateien mit den Jpeg-Bildern darin in ein Array of TJpegImage speichern und dann das Array komplett in den Blob speichern und später wieder lesen als Array. Ist das machbar ? und wie ist die Syntax, wäre froh über ein Beispiel. Wie mache ich das am Besten mit den Zip-Dateien aus der alten DB. Ich nehme an in einen MemoryStream lesen und dann mit der Zip-Lib irgendwie auspacken und dann die einzelnen Bilder in ein Array of TJpegImage speichern. Ein Beispiel dazu wäre schön. Eine weitere Frage ist wie es mit der Größe von Arrays aussieht, im Speicher und im Blob. Kann ich z.B. ein Array [0..120] of TJpegImage anlegen und dann nur 40 Einträge beschreiben, werden dann nur die Bytes der 40 Bilder als Speicherbedarf wirksam oder wird der Speicher für alle Bilder gleich angelegt ? (vom kleinen Overhead des Arrays mal abgesehen) Bin für jede Hilfe dankbar |
AW: Array of TJepeg in Blob schreiben und lesen
Ich würde statt eines Array eine TObjectList, ggf. eine generische, nehmen. Dann kannst du mit der richtigen ZIP-Komponente direkt in das Objekt speichern (SaveToStream, LoadFromStream, ggf. über ein TMemoryStream)
EDIT: Mit der TObjectList wäre das Problem der „Array-Länge“ auch vorbei... |
AW: Array of TJepeg in Blob schreiben und lesen
Du meinst bestimmt das ZipForge Programm zum entpacken.
Hast Du ein Beispiel wie ich eine Zip Datei damit in einen Memory Stream bekomme ? Und wie lese ich die einzelnen Dateien dann aus dem Stream ? den müsste ich ja irgendwie vom Typ her spezifizieren sonst ist es ja nur eine Ansammlung von Bytes. Zum Array ging es mir ums Prinzip. Ich kann ja auch ein Dynamisches Array nehmen, da ich die Anzahl der Dateien in der Datenbank mit abspeichere. Wollte nur wissen ob es sich drastisch auswirkt, wenn man ein größeres Array anlegt als das was man braucht und wie groß der Verlust ist. Denke mir, wenn ich nur ein bild in ein Array of 100 reinschreibe, sollte der speicherverbrauch doch nor 1xBildgröße + etwas overhead sein oder irre ich mich da ? |
AW: Array of TJepeg in Blob schreiben und lesen
Die Beispiele von ZipForge zeigen immer nur wie man aus oder in eine Datei schreibt/liest.
Die Stream Versionen auch nur wie man von Datei in Stream oder Strem in Datei schreib. Genau von dem Dateisystem will ich ja weg. Und wie bekomme ich die Zipdatei aus dem Blob erst mal in einen Stream und von da aus in ein ansprechbares Array oder ObjectList ? Manchmal helfen ja schon 2 zeilen um weiter zu kommen. ObjectList ist mir neu, muss ich weiter lesen was mir das genau bringt. sieht aus als wäre das sowas wie eine Stringlist mit beliebigen Objekten. Danke für die Anregung |
AW: Array of TJepeg in Blob schreiben und lesen
Ich denke du wirst nicht drumrumgekommen, die ZIP-Datei temporär auf der Platte zu speichern und z.B. bei ZiForge mittels ExtractToStream(Filename...) die Datei in das Image zu entpacken.
|
AW: Array of TJepeg in Blob schreiben und lesen
Danke für die Antwort, dann nützt mir ZipForge aber auch nichts.
Meine Zip-Dateien sind nur maximal 5 bis 10Mb groß, die muss ich nicht auf die Platte kopieren, dann bin ich wieder da wo ich schon mit der alten Version war. |
AW: Array of TJepeg in Blob schreiben und lesen
Warum nicht pro Blob "ein" Bild,
anstatt alles in einen Blob zu mantschen? |
AW: Array of TJepeg in Blob schreiben und lesen
Die meisten meine DB-Einträge sind einzelne Bilder.
Es gibt jedoch auch Bildfolgen mit 120 Bildern pro Video. Es macht wenig Sinn 120 Datensätze für ein Objekt abzulegen das man immer zusammen verwenden muss. Habe noch nicht gesehen, dass jemand Videos als Einzelbilder abspeichert. Es sind 120 Bilder die in einer Zeitlichen abfolge abgespielt werden. Die Lösung für Einzelbilder habe ich ja schon gepostet, nur für die Videos klappt das noch nicht. |
AW: Array of TJepeg in Blob schreiben und lesen
Es gibt aber auch keinen Sinn etwas zusammenzupappen, was du dann sowieso wieder zerlegen mußt, um es zu benutzen. :zwinker:
Zitat:
* oder wirklich zusammen, als ein Ding (z.B. als MJPEG oder ein anderes Videoformat) Zitat:
Stream -> TMemoryStream statt TFileStream und k.A. was "Filename" da oben zu suchen hatte, wenn es doch "Stream" heißt :stupid: Ja, die ZIP kann ein Stream sein ![]() aber auch die Dateien können aus einem Stream und bestimmt auch in einen Stream ![]() ![]() |
AW: Array of TJepeg in Blob schreiben und lesen
@Himitsu
Die Beispiele von ComponetAce habe ich mir angesehen. Zu deinem ersten Link Zitat:
FileName := 'C:\test.zip'; OpenArchive(fmCreate); BaseDir := 'C:\'; fileStream := TFileStream.Create('C:\test.txt', fmOpenReadWrite); AddFromStream('anothername.txt', fileStream); CloseArchive(); Bei den anderen Beispielen dasselbe, es ist immer nur eine Seite ein Stream, die andere Seite ist eine Datei. Außerdem hat scrat1979 geschrieben Zitat:
Zitat:
Ein Video daraus zu machen bedeutet 40ms lang das gleiche Bild zu duplizieren und damit die Datei enorm aufzublähen. Der Sinn dieser Bildfolge ist es mit möglichst wenigen Bildern eine noch flüssige Bewegung zu zeigen um Platz zu sparen. Die optimalste Art das zu speichern ist meiner Ansicht nach, ein Jpeg-Array. Meine Frage ist: Kann man ein Array aus Bildern in einen Blob speichern (sollte doch machbar sein) und kann man sie auch wieder in diesem Format herausholen und wie ist die Syntax dazu. Der Code in meinem Beispiel unter // Video einlesen und in Image schreiben if (AktData.Typ = 'V') then ist nur so dahingeschrieben um zu zeigen was ich machen will, ich denke nicht, dass es genauso machbar ist. Trotzdem Danke dass Du Dir Gedanken dazu gemacht hast Himitsu |
Alle Zeitangaben in WEZ +1. Es ist jetzt 22:26 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz