需要一种方法来计算tcanvas

时间:2018-03-08 18:43:52

标签: delphi tbitmap tcanvas

我使用paintbox组件使用rect,polygon和其他canvas方法绘制各种形状。用户创建绘图后,我想保存位图以便在列表框中使用。问题是绘图可能只使用画布的一小部分,并且列表框中的结果图像将非常小,除非我通过仅选择绘制框的原始画布的已使用部分来调整其大小。所以问题是我如何确定画布的哪个部分被使用,所以我只能提取画布的那部分加载到位图中以便在列表框中显示?

(注意:我上面编辑过一点来澄清这个问题)

实际程序有一个paintbox(200x200)和一个图像(32 x 32)。图像使用Bitmap1.Canvas.CopyRect(Dest, PaintBox1.Canvas, Source);从绘图框中获取其位图。如果绘图框中的绘图在200x200 paintbox.canvas中仅为20x20,则Image.canvas中的结果位图在32x32 image.canvas中将非常小。我需要它放大,这意味着我必须确定绘图箱中使用区域的实际大小,并在'CopyRec'中更改源大小。

1 个答案:

答案 0 :(得分:0)

我制定的一种方法是基于这样的假设,即绘制的各种项目(如圆形,矩形,文本等)都放在中性背景上。在这种情况下,我可以使用tbitmap.scanline读取位图,以比较绘图颜色与背景颜色,并计算每行中绘图的范围,以确定整个位图中绘图的范围。

  TRGBTriple = packed record
    rgbtBlue: Byte;
    rgbtGreen: Byte;
    rgbtRed: Byte;
  end;
  TRGBTripleArray = ARRAY[Word] of TRGBTriple;
  pRGBTripleArray = ^TRGBTripleArray; // use a PByteArray for pf8bit color

function findBMPExtents (Bmp : tbitmap; BkgdClr : longint):trect;
// finds the extents of an image in a background or BkgdClr color
//works on 24 bit colors
var
  P : pRGBTripleArray;
  x,y : integer;
  tfound, bfound, done : boolean;
  WorkTrpl : TRGBTriple;
  WorkRect : trect;
begin
  result.top := 0;
  result.bottom := Bmp.height;
  result.left := Bmp.Width;
  result.right := 0;
  tfound := false;
  bfound := false;
  WorkTrpl := getRGB (BkgdClr);

  //find left and top
  y := 0;
  done := false;
  Repeat
    P := Bmp.ScanLine[y];
    x := 0;
    Repeat
      if (p[x].rgbtBlue <> WorkTrpl.rgbtBlue) or
         (p[x].rgbtGreen <> WorkTrpl.rgbtGreen) or
         (p[x].rgbtRed <> WorkTrpl.rgbtRed) then
        begin
          tfound := true;
          if x <= result.left then begin
            result.left := x;
            done := true;
          end;
        end;
      inc (x);
    until (x = bmp.width) or done;
    done := false;
    inc (y);
    if not tfound then
      inc(result.top);
  until (y = bmp.height);

  //find right and bottom
  y := bmp.height - 1;
  done := false;
  Repeat
    P := Bmp.ScanLine[y];
    x := bmp.width-1;
    Repeat
      if (p[x].rgbtBlue <> WorkTrpl.rgbtBlue) or
         (p[x].rgbtGreen <> WorkTrpl.rgbtGreen) or
         (p[x].rgbtRed <> WorkTrpl.rgbtRed) then
        begin
          bfound := true;
          if x >= result.right then begin
            result.right := x;
            done := true;
          end;
        end;
      dec (x);
    Until (x = 0) or done;
    if not bfound then
      dec(result.bottom);
    done := false;
    dec (y);
  Until (y = -1);
  dec(result.bottom);
end;