Lainkes 0 Posted August 10, 2022 Good morning, I read the information from an ID card into my form. I have all the info, and also a TImage component with the picture. Now I want to save the content of this TImage component to my database (mysql - firedac - blob field). What is the best way to do this? And how can I read the blob field, so that the image can be displayed again in another form? Many thanks Lainkes Share this post Link to post
Uwe Raabe 2057 Posted August 10, 2022 What about using TDBImage instead of TImage? Share this post Link to post
Lainkes 0 Posted August 10, 2022 Hello, Yes, I tried DBImage and linked the correct field to it. But when starting the application I get an error "unformatted stream format". And I have no idea how to solve this. Share this post Link to post
Lajos Juhász 293 Posted August 10, 2022 In the older version TDBImage didn't supported anything but bitmaps. That's why we used TEDBImage (there are also other sources still floating on the internet how to handle multiple formats in a blob stream). Share this post Link to post
Uwe Raabe 2057 Posted August 10, 2022 20 minutes ago, Lajos Juhász said: In the older version TDBImage didn't supported anything but bitmaps. That's correct. So we need to know the Delphi version being used. Share this post Link to post
Lainkes 0 Posted August 10, 2022 I'm using Delphi 10.2. I have some code to write the image to my database. // Save IMAGE to database AStream := TMemoryStream.Create; try imgPerson.Picture.Graphic.SaveToStream(AStream); AStream.Position := 0; (FieldByName('VIS_IMAGE') as TBlobField).LoadFromStream(AStream); finally AStream.Free; end; And when I look in the DB, I see a lot of Ascii characters. So I guess the image is stored in the blob field. But how can I read this and store again in a TImaage field? The fieldname is imgPerson. I have this code (found via Google). But the TImage component stays empty. // read image AStream := TMemoryStream.Create; try begin TBlobField(DM_EID_READER.FD_Visitor.FieldByName('VIS_IMAGE')).SaveToStream(AStream); AStream.Position := 0; imgPerson.Picture.LoadFromStream(AStream); end; finally AStream.Free; end; Thanks Share this post Link to post
Fr0sT.Brutal 900 Posted August 10, 2022 3 minutes ago, Lainkes said: But how can I read this and store again in a TImaage field? Try this // Load JPG or PNG image from stream to picture. Format is auto detected. // Raise exception if something's wrong procedure LoadImageFromStream(Image: TImage; Stream: TStream); const JPGHeader: array[0..1] of Byte = ($FF, $D8); PNGHeader: array[0..3] of Byte = ($89, Byte('P'), Byte('N'), Byte('G')); var graphic: TGraphic; Header: array of Byte; begin graphic := nil; SetLength(Header, Max(Length(JPGHeader), Length(PNGHeader))); if Stream.Size > Length(Header) then try // Determine format by header Stream.Read(Pointer(Header)^, Length(Header)); if CompareMem(Header, @JPGHeader, Length(JPGHeader)) then graphic := TJPEGImage.Create else if CompareMem(Header, @PNGHeader, Length(PNGHeader)) then graphic := TPNGObject.Create else raise Exception.Create('Unsupported image format'); // Read the picture Stream.Position := 0; graphic.LoadFromStream(Stream); Image.Picture.Assign(graphic); finally FreeAndNil(graphic); end; end; ... if not Q.Query.FieldByName('Photo').IsNull then begin StmPhoto := TADOBlobStream.Create(Q.Query.FieldByName('Photo') as TBlobField, bmRead); try LoadImageFromStream(imgPhoto, StmPhoto); except on E: Exception do MessageDlg('Error loading photo:' + sLineBreak + E.Message, mtError, [mbOK], 0); end; StmPhoto.Free; end; 1 Share this post Link to post
Lainkes 0 Posted August 10, 2022 (edited) I'm getting a type cast error. I guess it's the StmPhoto variable. I defined it as a TMemoryStream. Also defining it as TStream give the same error. Any idea what I'm missing? Edited August 10, 2022 by Lainkes Share this post Link to post
Fr0sT.Brutal 900 Posted August 10, 2022 Use the proper FireDAC's BLOBStream type instead of TADOBlobStream Share this post Link to post
skyzoframe[hun] 4 Posted August 24, 2022 (edited) //Upload Using Parameters -FMX var Qcon : TFDConnection; Q : TFDQuery; mStr : TMemoryStream; Mezo : TField; begin Qcon := TfdConnection.Create(Self); try DBCon(Qcon); // procedure for setting up connection details. Q := TfdQuery.Create(Self); try Q.Connection := QCon; try Q.SQL.Text := 'select max(id) as Maxid from MGR_BLOB'; // Get max ID Q.Open; try Mezo := Q.FieldByName('Maxid'); if Mezo.IsNull then MGR_BLOB_ID := 0 else MGR_BLOB_ID := Mezo.AsInteger+1; finally Q.Close; end; finally Q.Params.Clear; Q.Params.Add.Name := 'ID'; Q.Params.Add.Name := 'BLOB01_KEY'; Q.Params.Add.Name := 'BLOB01'; Q.ParamByName('ID').AsInteger := MGR_BLOB_ID; Q.ParamByName('BLOB01_KEY').AsBoolean := Boolean(1); mStr := TMemoryStream.Create; try mStr.LoadFromFile(ZipPath); Q.ParamByName('BLOB01').LoadFromStream(mStr,ftBlob); Q.SQL.Text := ('insert into MGR_BLOB (BLOB01,'+sLineBreak +'BLOB01_KEY,'+sLineBreak +'ID)'+sLineBreak +'values'+sLineBReak +'(:BLOB01,'+sLineBreak +':BLOB01_KEY,'+sLineBreak +':ID)'); finally mStr.DisposeOf; end; finally Q.ExecSQL; end; finally Q.DisposeOf; end; finally Qcon.DisposeOf; end; end; Edited August 24, 2022 by skyzoframe[hun] Share this post Link to post
Lainkes 0 Posted October 13, 2022 Hello, I'm taking this up again. I was wondering what I need to use in FireDac to replace the TADOBlobStream command. For this code : StmPhoto := TADOBlobStream.Create(Q.Query.FieldByName('Photo') as TBlobField, bmRead); I'm still trying to read the image from my Blob field in to my TImage component. Thanks Share this post Link to post
haentschman 92 Posted October 13, 2022 (edited) Hi...😎 try this...😉 if not Qry.FieldByName('Picture').IsNull then begin Stream := TMemoryStream(Qry.CreateBlobStream(Qry.FieldByName('Picture'), bmRead)); try Contact.Picture := TMemoryStream.Create; Contact.Picture.LoadFromStream(Stream); finally Stream.Free; end; end; before...Contact.Picture = nil 😉 Edited October 13, 2022 by haentschman 1 Share this post Link to post
Lajos Juhász 293 Posted October 13, 2022 If everything fails read the manual: https://docwiki.embarcadero.com/Libraries/Sydney/en/FireDAC.Comp.DataSet.TFDDataSet.CreateBlobStream 1 Share this post Link to post
Lajos Juhász 293 Posted October 13, 2022 1 minute ago, haentschman said: Contact.Picture := TMemoryStream.Create; This cannot be correct my guess is Contact.Picture:=nil; ??? Share this post Link to post
haentschman 92 Posted October 13, 2022 (edited) ...see editing Quote before...Contact.Picture = nil 😉 ...is my case. Sometimes i read the Picture to a new object (Picture = nil) Edited October 13, 2022 by haentschman Share this post Link to post
Lainkes 0 Posted October 13, 2022 This works fine. Many thanks. Sometimes I wonder where you guys find all this information. Share this post Link to post
haentschman 92 Posted October 13, 2022 (edited) ...learning by doing. 😎 You can also adapt the example to your circumstances. Release of the stream. etc. Edited October 13, 2022 by haentschman Share this post Link to post