[Solved] Show external images in a dbgrid lazarus / 16-Databases ---------------------------------------------------------------------- WimVan · 2018-12-07 13:23 Some one did this already ? I want to show images in a dbgrid.  The database just owns the imagename and the folder where to find that image on the server. 1) is there a component to show images with correct ratio in the dbgrid.  As I saud, the image is kept outside the database.  Only a reference to the image is hold in two different fields in the database (foto and foto_dir) 2) if there is no component, what must I do  ?  I already tried using the ondrawcoulmcell-event but I lose all tracks ... Thanks Wim ---------------------------------------------------------------------- mangakissa · 2018-12-07 14:20 http://delphiexamples.com/databases/gridimages.html ---------------------------------------------------------------------- WimVan · 2018-12-07 20:33 I tried that after adapting some properties ...  But result was faulting.... And how to get the value of the foto_dir field when drawing the cell for the foto-field as an image ? ---------------------------------------------------------------------- mangakissa · 2018-12-08 07:38 I don't know when the picture from disk has to be loaded, but you can create a function where the picure will be loaded by stream. TFilestream has a loadfromfile function ---------------------------------------------------------------------- paweld · 2018-12-08 07:59 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 uses  fpimage, fpreadjpeg, fpreadpng, fpreadbmp, fpreadgif, fpreadtiff, fpwritebmp; procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;  DataCol: Integer; Column: TColumn; State: TGridDrawState);var  bmp: TBitmap;  image: TFPCustomImage;  reader: TFPCustomImageReader;  writer: TFPCustomImageWriter;  fotostream: TStream;begin  if Column.Index=1 then  begin    try      image:=TFPMemoryImage.Create(1, 1);      writer:=TFPWriterBMP.Create;      fotostream:=TStream.Create;      bmp:=TBitmap.Create;      case ExtractFileExt(ZQuery1.FieldByName('foto').AsString) of      '.bmp': reader:=TFPReaderBMP.Create;      '.jpg', '.jpeg': reader:=TFPReaderJPEG.Create;      '.png': reader:=TFPReaderPNG.Create;      '.gif': reader:=TFPReaderGif.Create;      '.tif', '.tiff': reader:=TFPReaderTIFF.Create;      end;      if image.LoadFromFile(ZQu ery1.FieldByName('foto_dir').AsString+ZQuery1.FieldByName('foto').AsSt ring, reader) then      begin        image.SaveToStream(fotostream, writer);        fotostream.Position:=0;        bmp.LoadFromStream(fotostream, fotostream.Size);        DBGrid1.Canvas.StretchDraw(Rect, bmp);      end;    finally      writer.Free;      image.Free;      bmp.Free;      fotostream.Free;    end;  end;end; ---------------------------------------------------------------------- WimVan · 2018-12-09 10:42 Quote from: paweld on December 08, 2018, 08:59:08 amCode: Pascal  [Select][+][-]window.onload = function(){var x1 = document.getElementById("main_content_section"); if (x1) { var x = document.getElementsByClassName("geshi");for (var i = 0; i uses  fpimage, fpreadjpeg, fpreadpng, fpreadbmp, fpreadgif, fpreadtiff, fpwritebmp; procedure TForm1.DBGrid1DrawColumnCell(Sender: TObject; const Rect: TRect;  DataCol: Integer; Column: TColumn; State: TGridDrawState);var  bmp: TBitmap;  image: TFPCustomImage;  reader: TFPCustomImageReader;  writer: TFPCustomImageWriter;  fotostream: TStream;begin  if Column.Index=1 then  begin    try      image:=TFPMemoryImage.Create(1, 1);      writer:=TFPWriterBMP.Create;      fotostream:=TStream.Create;      bmp:=TBitmap.Create;      case ExtractFileExt(ZQuery1.FieldByName('foto').AsString) of      '.bmp': reader:=TFPReaderBMP.Create;      '.jpg', '.jpeg': reader:=TFPReaderJPEG.Create;      '.png': reader:=TFPReaderPNG.Create;      '.gif': reader:=TFPReaderGif.Create;      '.tif', '.tiff': reader:=TFPReaderTIFF.Create;      end;      if image.LoadFromFile(ZQu ery1.FieldByName('foto_dir').AsString+ZQuery1.FieldByName('foto').AsSt ring, reader) then      begin        image.SaveToStream(fotostream, writer);        fotostream.Position:=0;        bmp.LoadFromStream(fotostream, fotostream.Size);        DBGrid1.Canvas.StretchDraw(Rect, bmp);      end;    finally      writer.Free;      image.Free;      bmp.Free;      fotostream.Free;    end;  end;end;       Hi, Thanks, I tried out this code but I met some errors. image.LoadFromFile    is a function which returns a boolean if (not) successful, but you may pass just one parameter. I adapted it, but hen I ran the program, I got a compilation error indicating that Tstream.seek is NOT implemented. Looking on the forum about this error, some people propose using TMemoryStream What is the quickest and what consumes less memory ? Thanks any way ---------------------------------------------------------------------- wp · 2018-12-09 12:00 Quote from: WimVan on December 09, 2018, 11:42:22 amWhat is the quickest and what consumes less memory ? You are talking of a "fotostream" and probably have the huge >20 mega pixel photos in mind - this will always be slow even if you use a memory stream because you must read the file and decode the jpeg. Whenever you drag another window over your dbgrid or you drag the grid out of the visible desktop area the required repaint will have to reload the original images. I'd write the stretchdrawn image to a Bitmap and use this to display the images. A 300x200 uncompressed image (0.24MB) is much smaller than the original many-megapixel file and is already decoded. If the dataset has many rows you should set up a cache for the size-reduced images. Whenever you load an original image stretch-draw it and save the reduced image to a cache folder. When you want to draw a cell you should look whether an already reduced image exists in the cache and load it from there, otherwise you should stretchdraw the image to another cached file. When the dataset scrolls the grid should delete the images attached to inivisible records and load only those visible. It will be lot of work, though... ---------------------------------------------------------------------- WimVan · 2018-12-09 15:00 @wp Correct, but this something I know.  That's why I always keep all photo's outside the database. In the database resides only a n image-name and a part of the directory where resides the photo. However, on the harddisk I have 3 similar directory FolderX\originals\\ FolderX\slides\\ FolderX\thumbs\\ When creating a overview in a grid, I use thumb-presentation When creating a full-screen-image I uses the slide-option When looking to the reall image (can be 36 MP) I use the original option. Tho construct the real path, I have just to choose between originals, slides or thumbs. This work extremely quick. Of course, the select has his limitation where I only permit a max of 100 images... Ok, all photo's are kept 3 times.  One with full size, one with a 1024-768-base and one with 250-250-base. So we talk about 35 MP or higher, ¹200Kb and ±6Kb For the moment I own about 130.000 images and I once wrote a program to maintain, order, tag, ... this with PHP and HTML.  Program is still used and runs now for more than 15 years ...  Now I would like to have an exe that runs without HTML, PHP. But thanks for the useful info ---------------------------------------------------------------------- WimVan · 2018-12-09 20:09 Next code is running finally. I used TImage because it is more versatile and some properties are usefull 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  image : TImage;  foto : string;begin  if Column.Index=2 then  begin    image := TImage.Create(Self);    try      foto := DIR_SLIDE+SQLQuery1.FieldB yName('foto_dir').AsString+'\'+SQLQuery1.FieldByName('foto').AsString;     case ExtractFileExt(foto) of      '.bmp': image.Picture.Bitmap.LoadFromFile(foto);      '.jpg', '.jpeg': image.Picture.Jpeg.LoadFromFile(foto);      '.png': image.Picture.PNG.LoadFromFile(foto);      end;      DBGrid1.Canvas.Draw(Rect.left, Rect.Top, image.Picture.Graphic);    finally      image.Free;    end;  end;end;  Next to do is center the image, resize ... but Timage-properties does a lot of these ---------------------------------------------------------------------- wp · 2018-12-09 20:50 You don't have to check the extension. Image.Picture.LoadFromFile is all that you need, it checks the file format and creates the correct bitmap class. And you even don't need a TImage, you can create a TPicture independently: 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 : string;begin  if Column.Index=2 then  begin    pic := TPicture.Create;    try      foto := DIR_SLIDE+SQLQuery1.FieldByNam e('foto_dir').AsString+'\'+SQLQuery1.FieldByName('foto').AsString;    pic.LoadFromFile(foto);      DBGrid1.Canvas.Draw(Rect.left, Rect.Top, pic);    finally      pic.Free;    end;  end;end; ---------------------------------------------------------------------- WimVan · 2018-12-09 21:07 Correct, but then I do not heve properties like strech, autosize, ... and these I'm tending to use. ---------------------------------------------------------------------- mangakissa · 2018-12-10 07:40 QuoteCorrect, but then I do not heve properties like strech, autosize, ... and these I'm tending to use. Code: [Select]DBGrid1.Canvas.Draw(Rect.left, Rect.Top, pic);Why stretching if this procedure draws the picture in the size of the painted row? ---------------------------------------------------------------------- WimVan · 2018-12-10 09:07 Quote from: mangakissa on December 10, 2018, 08:40:35 amQuoteCorrect, but then I do not heve properties like strech, autosize, ... and these I'm tending to use. Code: [Select]DBGrid1.Canvas.Draw(Rect.left, Rect.Top, pic);Why stretching if this procedure draws the picture in the size of the painted row? Also correct, but I just wrote that there are some properties that can be very usefull. I didn't used them here.  It just serves as how I can show an image in the DBGrid