Search code examples
delphidelphi-xe2tlistviewtimagelist

Displaying images from db on the go


In Delphi I have an unknown number of image file names stored in a details table. These image files can be Bitmaps, Jpegs, PNGS and ICO files.

What's the paradigm / best practice to load and display those in a listview or a listbox on the go?
I take it I would somehow need to load those to a ImageList in OnBeforeScroll event of a master table and then assign that to a listview. Database components used are dbGO.

I only need to display thumbnails of predefined size (in a VCL program).


Solution

  • The simplest method is to use TPicture, since the loading of different graphic formats is already implemented and you do have to care about different image classes .
    You have to ensure that the required units are included in the with uses so here e.g. jpeg, gifimg, and pngimg.
    After loading with TPicture.LoadFromFile the images are painted, centered and scaled, on a prepared Bitmap with the dimensions of the Imagelist.
    Last step is simply to call teh AddBitmap procedure with the Bitmap and nil for the mask.

    // make sure you included the needed units
    // uses pngImage,jpeg,gifimg;
    
    Procedure LoadImagesFromDataset2ImageList(il: TImageList; DS: TDataset; const FileFieldname: String);
    var
      P: TPicture;
      bmp: TBitmap;
    
      Function CalcRectAndPrepare: TRect; // calculate Rect for here centered/streched output
      var // and fill the bitmap with the desired beckground color
        f: Double;
      begin
        bmp.Canvas.Brush.Color := clWhite;
        bmp.Canvas.FillRect(Rect(0, 0, bmp.Width, bmp.Height));
        if P.Width > P.Height then
          f := bmp.Width / P.Width
        else
          f := bmp.Height / P.Height;
        Result.Left := Round(bmp.Width - P.Width * f) div 2;
        Result.Top := Round(bmp.Height - P.Height * f) div 2;
        Result.Right := bmp.Width - Result.Left;
        Result.Bottom := bmp.Height - Result.Top;
      end;
    
    begin
      P := TPicture.Create;
      bmp := TBitmap.Create;
      try
        bmp.Width := il.Width;
        bmp.Height := il.Height;
        DS.First;
        while not DS.Eof do
        begin
          if FileExists(DS.Fieldbyname(FileFieldname).asString) then
          begin
            P.LoadFromFile(DS.Fieldbyname(FileFieldname).asString);
            bmp.Canvas.StretchDraw(CalcRectAndPrepare, P.Graphic);
            il.Add(bmp, nil);
          end;
          DS.Next;
        end;
      finally
        P.Free;
        bmp.Free;
      end;
    end;