Delphi DrawGrid 只显示第一张图片

Delphi DrawGrid only displays first image

我想在 TDrawGrid 中显示图像列表。在下面的示例中,我的 DrawGrid 仅显示一个图像及其第一张图像。其他 2 个图像不显示在网格中。网格的RowCount是3,ColCount是1.

procedure DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  Rect: TRect; State: TGridDrawState);
var
  Bmp: TBitmap;
  R: TRect;
  JImg: TJPEGImage;
begin
  JImg := TJPEGImage.Create;
  Bmp := TBitmap.Create;

  try
    JImg.LoadFromFile('c:\tmp\photo'+IntToStr(ARow+1)+'.jpeg');

    Bmp.PixelFormat := pf24bit;
    Bmp.Width := 73;
    Bmp.Height := 73;

    R.Top := Rect.Top + 1;
    R.Left := Rect.Left + 1;
    R.Right := R.Left + 73;
    R.Bottom := R.Top + 73;
    Bmp.Canvas.StretchDraw(R, JImg);
    DrawGrid1.Canvas.StretchDraw(R, Bmp);
  finally
    JImg.Free;
    Bmp.Free;
  end;
end;
R.Top := Rect.Top + 1;
....
Bmp.Canvas.StretchDraw(R, JImg);

此代码在位图的移位区域绘制 jpeg,因此您看不到它。

在位图活动区域定义矩形。可能的方式:

  R.Top := 0;
  R.Left := 0;
  R.Right := 73;
  R.Bottom := 73;

  Bmp.Canvas.StretchDraw(R, JImg);
  OffsetRect(R, Rect.Left + 1, Rect.Top + 1);
  DrawGrid1.Canvas.StretchDraw(R, Bmp);

您正在使用错误的 TRect 值将 TJPEGImage 绘制到 TBitmap 上。您使用的值是相对于网格的,而不是 TBitmap,因此第二张和后续图像是在 TBitmap 的边界之外绘制的。

您需要使用更像这样的东西:

procedure DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  ARect: TRect; State: TGridDrawState);
var
  Bmp: TBitmap;
  R: TRect;
  JImg: TJPEGImage;
begin
  JImg := TJPEGImage.Create;
  try
    JImg.LoadFromFile(Format('c:\tmp\photo%d.jpeg', [ARow+1]));

    Bmp := TBitmap.Create;
    try
      Bmp.PixelFormat := pf24bit;
      Bmp.Width := 73;
      Bmp.Height := 73;

      R := Rect(0, 0, Bmp.Width, Bmp.Height);
      Bmp.Canvas.StretchDraw(R, JImg);

      R.Offset(ARect.Left, ARect.Top);
      DrawGrid1.Canvas.StretchDraw(R, Bmp);
    finally
      Bmp.Free;
    end;
  finally
    JImg.Free;
  end;
end;

然而,实际上根本不需要 TBitmap,因为您可以将 TJPEGImage 直接绘制到网格的 Canvas 上:

procedure DrawGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
  ARect: TRect; State: TGridDrawState);
var
  R: TRect;
  JImg: TJPEGImage;
begin
  JImg := TJPEGImage.Create;
  try
    JImg.LoadFromFile(Format('c:\tmp\photo%d.jpeg', [ARow+1]));

    R := Rect(0, 0, 73, 73);
    R.Offset(ARect.Left + 1, ARect.Top + 1);
    DrawGrid1.Canvas.StretchDraw(R, JImg);
  finally
    JImg.Free;
  end;
end;

也就是说,每次在屏幕上重新绘制网格时,此代码都会重新加载 .jpeg 文件。您应该一次性加载文件并缓存图像,例如在 TImageList 中。或者,根本不使用 TDrawGrid。例如,您可以在 TScrollBox 上放置一系列 TImage 控件,然后将 .jpeg 文件加载到 TImage 控件中,让它们为您处理绘图。