You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi 11 VCL中CopyRect裁剪图像生成0尺寸结果问题求助

Delphi 11 VCL中CopyRect/BitBlt裁剪图像生成0尺寸图的解决方法

你遇到的核心问题是创建后的OutBitmap默认宽高为0——不管用CopyRect还是BitBlt,都无法在尺寸为0的画布上绘制任何内容,最终自然生成0尺寸的空图。

修复方案

在CropBitmapVCL函数里,设置OutBitmap.PixelFormat之前,必须先指定OutBitmap的宽高(即裁剪区域的宽度和高度)。

修改后的完整代码

procedure TForm2.Button1Click(Sender: TObject);
var
  TxferBMP, OPBMP : TBitmap;
begin
  TxferBMP := TBitmap.Create;
  OPBMP := TBitmap.Create;
  try
    TxferBMP.Assign(imgSource.Picture.Graphic);
    CropBitmapVCL(TxferBMP, OPBMP, 300, 200, 100, 80);
    imgCropped.Picture.Assign(OPBMP);
  finally
    TxferBMP.Free;
    OPBMP.Free;
  end;
end;

procedure TForm2.CropBitmapVCL(InBitmap : TBitmap; var OutBitmap : TBitmap; X, Y, W, H :integer);
var
  iRect, oRect: TRect;
  TmpFileName: string;
begin
  // 可选:校验裁剪参数是否合法,避免超出源图像范围
  if (X < 0) or (Y < 0) or (W <=0) or (H <=0) or (X+W > InBitmap.Width) or (Y+H > InBitmap.Height) then
  begin
    ShowMessage('裁剪参数超出图像范围');
    Exit;
  end;

  iRect.Left := X;
  iRect.Top := Y;
  iRect.Width := W;
  iRect.Height := H;
  oRect.Left := 0;
  oRect.Top := 0;
  oRect.Width := iRect.Width;
  oRect.Height := iRect.Height;

  // 关键修复:先设置输出Bitmap的宽高,否则画布尺寸为0无法绘制
  OutBitmap.Width := W;
  OutBitmap.Height := H;
  OutBitMap.PixelFormat := InBitmap.PixelFormat;

  TmpFileName := IncludeTrailingPathDelimiter(ApplicationPath) + 'InBitmap.jpg';
  InBitmap.SaveToFile(TmpFileName);
  lblSrcImgSize.Caption := ('Src: ' + IntToStr(InBitmap.Width) + ' : ' + IntToStr(InBitmap.Height));

  // 使用CopyRect裁剪
  InBitmap.Canvas.CopyMode := cmSrcCopy;
  OutBitmap.Canvas.CopyRect(oRect, InBitmap.Canvas, iRect);

  // 如果改用BitBlt,同样需要先设置OutBitmap宽高,取消注释即可
  // BitBlt(OutBitMap.Canvas.Handle, oRect.Left, oRect.Top, oRect.Width, oRect.Height,
  //        InBitmap.Canvas.Handle, iRect.Left, iRect.Top, SRCCOPY);

  TmpFileName := IncludeTrailingPathDelimiter(ApplicationPath) + 'OutBitmap.jpg';
  OutBitmap.SaveToFile(TmpFileName);
  lblDstImgSize.Caption := ('Cropped: ' + IntToStr(OutBitmap.Width) + ' : ' + IntToStr(OutBitmap.Height));
end;

补充说明

TBitmap实例创建后默认宽高为0,必须手动指定目标尺寸,画布才会分配对应的绘制区域。另外添加参数校验可以避免因裁剪区域超出源图像范围导致的部分空白问题。

内容的提问来源于stack exchange,提问作者BennieC

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.19 21:10:47