需要一种方法来计算画布中实际图形项目的范围



我正在使用油漆盒组件使用矩形,多边形和其他画布方法绘制各种形状。 用户创建绘图后,我想保存位图以在列表框中使用。问题是绘图可能只使用画布的一小部分,并且列表框中生成的图像将非常小,除非我通过仅选择油漆框原始画布的已使用部分来调整其大小。因此,问题是如何确定使用了画布的哪个部分,以便我只能提取画布的该部分以加载到位图中以在列表框中显示?

(注:我上面编辑是为了澄清一下问题)

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

我制定的一种方法是基于以下假设:已绘制的各种项目(例如圆形,矩形,文本等)都放置在中性背景上。 在这种情况下,我可以使用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;

最新更新