[SOLVED] How to display image from DB in DBGrid? lazarus / 16-Databases ---------------------------------------------------------------------- Vodnik · 2019-09-24 19:57 USERS table in Informix DB that I'm working with have AVATAR column. It is of type BYTE and size 2147483647. Attached is screenshot how WinSQL shows it as "Raw data" (other tabs do not work). Being saved to file, it successfully opens as BMP. ...Well, it would be nice to show this avatar picture in DBGrid. Following discussion provides a solution for displaying external files: https://forum.lazarus.freepascal.org/index.php?topic=43467.0 But how to display image from DB in DBGrid? (I have no graphic experience yet) ---------------------------------------------------------------------- winni · 2019-09-24 20:55 Hi! The simple and slowest solution is this way: Save your raw data to a temporary file Create a TBitmap Load the file into this bitmap Compute your destination rectangle on the canvas of the DBGrid Do a Bitmap.Stretchdraw on the DBGrid.canvas Free the bitmap delete the temporary file done For a faster handling there might be a way to get the raw data into a memorystream and put it into the bitmap. But I have no idea how to do. Winni ---------------------------------------------------------------------- paweld · 2019-09-25 04:11 Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;  DataCol: Integer; Column: TColumn; State: TGridDrawState);var  pic: TPicture;  foto : TMemoryStream;begin  if Column.Index=2 then  begin  pic:=TPicture.Create;        foto:=TMemoryStream.Create;    try        foto.CopyFrom(SQLQuery1.CreateBlobStream(SQLQuery1.FieldByName('AVA TAR'), bmRead), 0);      pic.LoadFromStream(foto);      DBGrid1.Canvas.Draw(Rect.left, Rect.Top, pic);    finally      pic.Free;          foto.Free;    end;  end;end; ---------------------------------------------------------------------- Vodnik · 2019-09-30 15:14 @paweld, thank you for the idea! Though I didn't succeeded with it yet: 1. I replaced TPicture with TBitmap, because DBGridUsers.Canvas.Draw expects TGraphic, not TPicture: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TMainForm.DBGridUsersDrawColumnCell(Sender: TObject;  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);var  bmp: TBitmap;  foto : TMemoryStream;begin  if Column.FieldName='avatar' then  begin    foto:=TMemoryStream.Create;  bmp:=TBitmap.Create;    try      foto.CopyFrom(SQLQuery.CreateBlobStr eam(SQLQuery.FieldByName('avatar'), bmRead), 0);      bmp.LoadFromStream(foto);      DBGridUsers.Canvas.Draw(Rect.left, Rect.Top, bmp);    finally      bmp.Free;      foto.Free;    end;  end;end;  2. This function call raises exception class 'External: SIGSEGV': foto.CopyFrom(SQLQuery.CreateBlobStream(SQLQuery.FieldByName('avatar') , bmRead), 0); What may be the reason for that? ---------------------------------------------------------------------- Vodnik · 2019-09-30 18:18 Well, from docs: https://www.freepascal.org/docs- html/fcl/db/tdataset.createblobstream.html CreateBlobStream is not intended for use by application programmers. It creates a stream object which can be used to read or write data from a blob field. Instead, application programmers should use the TBlobField.LoadFromStream and TBlobField.SaveToStream methods when reading and writing data from/to BLOB fields Do somebody have a very simple example of using these functions? ---------------------------------------------------------------------- GAN · 2019-09-30 19:27 Quote from: Vodnik on September 30, 2019, 08:18:08 pmWell, from docs: https://www.freepascal.org/docs- html/fcl/db/tdataset.createblobstream.html CreateBlobStream is not intended for use by application programmers. It creates a stream object which can be used to read or write data from a blob field. Instead, application programmers should use the TBlobField.LoadFromStream and TBlobField.SaveToStream methods when reading and writing data from/to BLOB fields Do somebody have a very simple example of using these functions? Sure, this works for me. I use Zeos Lib but I think the result must be the same. Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TfrmBancos.btnAplicaClick(Sender: TObject);var  ms:TMemoryStream;begin  DMBcos.ZQBancos.Insert;  DMBcos.ZQBancos.FieldByName('nombre').AsString:=edNombre.Text;  //...rest of fields  if (logotipo.Picture.Width>0) then    begin      ms:=TMemoryStream.Create;      Logotipo.Picture.SaveToStream(ms);    ms.Position:=0;      TBlobField(DMBcos.ZQBancos.FieldByName('logo')).LoadFromStream(ms);    ms.Free;    end  else    begin      DMBcos.ZQBancos.FieldByName('logo').AsString:='';    end;  DMBcos.ZQBancos.Post;  //...end;   [/quote] ---------------------------------------------------------------------- Vodnik · 2019-10-01 22:04 Thanks, GAN! Now my procedure looks like: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TMainForm.DBGridUsersDrawColumnCell(Sender: TObject;  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);var  bmp: TBitmap;  foto : TMemoryStream;begin  if Column.FieldName='avatar' then  begin    foto:=TMemoryStream.Create;  bmp:=TBitmap.Create;    try      TBlobField(SQLQuery.FieldByName('avatar')).SaveToStream(foto);      bmp.LoadFromStream(foto);      DBGridUsers.Canvas.Draw(Rect.left, Rect.Top, bmp);    finally      bmp.Free;      foto.Free;    end;  end;end; There are no errors reported now, but there are also no pictures in the cells. Column 'Avatar' just shows text (blob) in each row. I also tried to draw just a rectangle in a cell 'Avatar'. Procedure fires, but result is the same. Is there any hint how the drawable column should be defined? ---------------------------------------------------------------------- wp · 2019-10-01 22:37 Maybe you must reset the stream (foto.Position := 0) after reading the image from the DB and before loading it into the bmp: Code: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i procedure TMainForm.DBGridUsersDrawColumnCell(Sender: TObject;  const Rect: TRect; DataCol: Integer; Column: TColumn; State: TGridDrawState);var  bmp: TBitmap;  foto : TMemoryStream;begin  if Column.FieldName='avatar' then  begin    foto:=TMemoryStream.Create;  bmp:=TBitmap.Create;    try      TBlobField(SQLQuery.FieldByName('avatar')).SaveToStream(foto);  // stream is at the end here      foto.Position := 0;  // rewind the stream to the start      bmp.LoadFromStream(foto);      DBGridUsers.Canvas.Draw(Rect.left, Rect.Top, bmp);    finally      bmp.Free;      foto.Free;    end;  end;end; ---------------------------------------------------------------------- Vodnik · 2019-10-02 07:49 @wp, thanks a lot, now it works!