我有一个游戏程序,要求用户从50多个图像中进行选择,以将其放置在9x9游戏棋盘格中,每个位置都带有timage
。为了让用户放置图像,我提供了tstringgrid
,该图像显示timagelist
中的各种图像。实际图像是以.png
格式创建的带有透明区域的图形符号,以使图像父级的背景色在显示时能够显示出来。从tstringgrid
中选择的图像可以正确显示在游戏板timage
组件上,但不能显示在'tstringgrid'中。 tstringgrid
将图像的透明区域显示为黑色,这不美观,并且使许多符号不可读。
我已使用以下代码加载tstringgrid
:
procedure TImageForm.FormCreate(Sender: TObject);
var
r, c, n : Integer;
img:TImage;
begin
//assign a value to each cell to connect with imagelist.
//see StringGrid1DrawCell
img := timage.Create(nil);
try
n := -1;
with StringGrid1 do begin
for r := 0 to RowCount - 1 do begin
for c:= 0 to ColCount - 1 do begin
inc(n);
Cells[c,r] := IntToStr(n);
ImageList1.GetBitmap(n, img.Picture.Bitmap);
// ImageList1.AddMasked(Img.Picture.Bitmap, clBlack);
end;
end;
end;
finally
img.Free;
end;
end;
我需要做的是在显示之前修改从列表中检索到的位图。
我正在尝试如下操作:
procedure TForm1.FillBkgd (bmp : tbitmap;clr : tcolor);
//which is the imagelist index for the image
var
bmp1 : tbitmap;
begin
bmp1 := tbitmap.create;
try
bmp1.Width := 50;
bmp1.Height := 50;
with Bmp1.Canvas do begin
Brush.Color := clr; //stringgrid1.color;
Brush.Style := bsSolid;
FillRect(rect(0,0,50, 50));
end;
bmp1.Canvas.Draw(0,0, bmp);
bmp:= bmp1;
finally
bmp1.free;
end;
end;
procedure TForm1.StringGrid1DrawCell(Sender: TObject; ACol, ARow: Integer;
Rect: TRect; State: TGridDrawState);
{https://www.youtube.com/watch?v=LOEP312NzsE}
var
bmp : tbitmap;
s : string;
aCanvas: TCanvas;
n : integer;
begin
inherited;
if not Assigned (Imagelist1) then //or (Arow = 0) or (aCol in [0,5])
exit;
bmp := tbitmap.create;
try
s := (Sender as TStringGrid).Cells [aCol, ARow];
// Draw ImageX.Picture.Bitmap in all Rows in Col 1
aCanvas := (Sender as TStringGrid).Canvas;
// Clear current cell rect
aCanvas.FillRect(Rect);
// Draw the image in the cell
n := strtoInt (s);
ImageList1.GetBitmap(n, Bmp);
FillBkgd (bmp,clRed); //stringgrid.color
aCanvas.StretchDraw(Rect,bmp);
finally
end;
end;
我尝试将符号图像与彩色背景组合在一起,然后再将其放置在stringgrid中,但失败了。我不清楚我是无法创建纯色位图还是没有成功将图像连接到背景。
函数FillBkgd
在代码质量上有很大问题。
bmp:= bmp1;
finally
bmp1.free;
end;
所有对象变量都是指针。 bmp
和bmp1
对象指向您要释放的内存区域。这会导致访问冲突。您很幸运没有从函数返回指针。功能FillBkgd
不起作用。要获得结果,可以使用bmp.Assign(bmp1);
。
我看到很多重绘ImageList的图片。第一次转换后,透明性信息丢失。因此,此时需要更改背景颜色。
s := (Sender as TStringGrid).Cells [aCol, ARow];
// Draw ImageX.Picture.Bitmap in all Rows in Col 1
aCanvas := (Sender as TStringGrid).Canvas;
// Clear current cell rect
aCanvas.FillRect(Rect);
// Draw the image in the cell
n := strtoInt (s);
//new lines
bmp.Canvas.Brush.Color := clRed;
bmp.Canvas.FillRect(TRect.Create(0, 0, ImageList1.Width, ImageList1.Height));
//new lines
ImageList1.GetBitmap(n, Bmp);
//deleted lines
//FillBkgd (bmp,clRed); //stringgrid.color
aCanvas.StretchDraw(Rect,bmp);
并且不要忘记填写finally
以释放bmp
。