12

指定された背景色キーを使用して、ビットマップのクローズクロップ長方形を計算する必要があります。次の写真では、何が近い作物であるかを見ることができます。左側はソース、右側はクローズクロップの出力です。

ここに画像の説明を入力してください

ここに画像の説明を入力してください

ご覧のとおり、クローズクロップの長方形を作成するには、背景と色が異なる最上部、左端、最下部、右端のピクセルを見つける必要があります。では、これらの異なる外側のピクセルを見つけて、近いクロップ長方形を取得するにはどうすればよいですか?または、言い換えると、ビットマップのクローズクロップ長方形を計算する方法は?

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 に答える