How to calculate close crop rectangle of a bitmap?

前端 未结 1 1652
慢半拍i
慢半拍i 2020-12-30 07:11

I need to calculate a close crop rectangle for a bitmap by a given background color key. In the following pictures you can see what is meant to be the close crop. On the lef

相关标签:
1条回答
  • 2020-12-30 07:33

    You can use this code (you may follow the commented version of this post as well):

    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;
    
    0 讨论(0)
提交回复
热议问题