我需要通过给定的背景颜色键计算位图的紧密裁剪矩形。在下面的图片中,您可以看到近距离裁剪的含义。左边是源,右边是close crop的输出:
如您所见,我需要找到与背景颜色不同的最顶部、最左侧、最底部和最右侧的像素来构建紧密裁剪矩形。那么,如何找到那些不同的外部像素来获得近距离裁剪矩形?或者,换句话说,如何计算位图的紧密裁剪矩形?
我需要通过给定的背景颜色键计算位图的紧密裁剪矩形。在下面的图片中,您可以看到近距离裁剪的含义。左边是源,右边是close crop的输出:
如您所见,我需要找到与背景颜色不同的最顶部、最左侧、最底部和最右侧的像素来构建紧密裁剪矩形。那么,如何找到那些不同的外部像素来获得近距离裁剪矩形?或者,换句话说,如何计算位图的紧密裁剪矩形?
您可以使用此代码(您也可以关注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;