12

我需要通过给定的背景颜色键计算位图的紧密裁剪矩形。在下面的图片中,您可以看到近距离裁剪的含义。左边是源,右边是close crop的输出:

在此处输入图像描述

在此处输入图像描述

如您所见,我需要找到与背景颜色不同的最顶部、最左侧、最底部和最右侧的像素来构建紧密裁剪矩形。那么,如何找到那些不同的外部像素来获得近距离裁剪矩形?或者,换句话说,如何计算位图的紧密裁剪矩形?

4

1 回答 1

12

您可以使用此代码(您也可以关注commented version这篇文章):

procedure CalcCloseCrop(ABitmap: TBitmap; const ABackColor: TColor;
  out ACropRect: TRect);
var
  X: Integer;
  Y: Integer;
  Color: TColor;
  Pixel: PRGBTriple;
  RowClean: Boolean;
  LastClean: Boolean;
begin
  if ABitmap.PixelFormat <> pf24bit then
    raise Exception.Create('Incorrect bit depth, bitmap must be 24-bit!');

  LastClean := False;
  ACropRect := Rect(ABitmap.Width, ABitmap.Height, 0, 0);

  for Y := 0 to ABitmap.Height-1 do
  begin
    RowClean := True;
    Pixel := ABitmap.ScanLine[Y];
    for X := 0 to ABitmap.Width - 1 do
    begin
      Color := RGB(Pixel.rgbtRed, Pixel.rgbtGreen, Pixel.rgbtBlue);
      if Color <> ABackColor then
      begin
        RowClean := False;
        if X < ACropRect.Left then
          ACropRect.Left := X;
        if X + 1 > ACropRect.Right then
          ACropRect.Right := X + 1;
      end;
      Inc(Pixel);
    end;

    if not RowClean then
    begin
      if not LastClean then
      begin
        LastClean := True;
        ACropRect.Top := Y;
      end;
      if Y + 1 > ACropRect.Bottom then
        ACropRect.Bottom := Y + 1;
    end;
  end;

  if ACropRect.IsEmpty then
  begin
    if ACropRect.Left = ABitmap.Width then
      ACropRect.Left := 0;
    if ACropRect.Top = ABitmap.Height then
      ACropRect.Top := 0;
    if ACropRect.Right = 0 then
      ACropRect.Right := ABitmap.Width;
    if ACropRect.Bottom = 0 then
      ACropRect.Bottom := ABitmap.Height;
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
var
  R: TRect;
  Bitmap: TBitmap;
begin
  CalcCloseCrop(Image1.Picture.Bitmap, $00FFA749, R);
  Bitmap := TBitmap.Create;
  try
    Bitmap.SetSize(R.Width, R.Height);
    Bitmap.Canvas.CopyRect(Rect(0, 0, R.Width, R.Height), Image1.Canvas, R);
    Image1.Picture.Bitmap.Assign(Bitmap);
  finally
    Bitmap.Free;
  end;
end;
于 2012-05-10T12:18:29.977 回答