Jump to content
Lainkes

Write image to database

Recommended Posts

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

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

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
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

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
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;

 

  • Like 1

Share this post


Link to post

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 by Lainkes

Share this post


Link to post
//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 by skyzoframe[hun]

Share this post


Link to post

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

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 by haentschman
  • Thanks 1

Share this post


Link to post
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

...see editing

Quote

before...Contact.Picture = nil 😉

 

...is my case. Sometimes i read the Picture to a new object (Picture = nil)

Edited by haentschman

Share this post


Link to post

...learning by doing. 😎

 

You can also adapt the example to your circumstances. Release of the stream. etc.

Edited by haentschman

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×