如何隐藏ScrollBox中TImage的黑色背景画布,仅显示绘制的蓝色线条?
解决TImage绘制网格时的黑色背景与透明需求问题
用户问题描述
在ScrollBox的子控件TImage上绘制蓝色网格线条,要求仅显示线条、无黑色背景(实现TImage透明)。现有代码存在两种异常情况:
- 不注释
with gridimage do代码块:绘制出的网格带有黑色背景 - 注释该代码块:网格无黑色背景,但绘制在了Form1上,且无法关闭
用户提供的原始代码:
procedure TForm1.gridButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var bm: TBitmap; hlines,vlines: word; begin if showgrid=true then begin showgrid:=false; if gridon=true then begin FreeAndNil(gridimage); gridon:=false; end; end else begin showgrid:=true; if gridon=false then begin gridimage:=TImage.Create(terrainScrBox); gridimage.Parent:=terrainScrBox; gridimage.Left:=0; gridimage.Top:=0; gridimage.width:=terrainCanvas.width; //terrainCanvas is a TImage component. gridimage.height:=terrainCanvas.Height; griddrawing(gridimage); end; gridon:=true; end; end; procedure TForm1.griddrawing(Sender: TObject); var hlines,vlines: word; begin vlines:=tilewidth; hlines:=tileheight; //with gridimage do // If these lines are commented, the grid is visible without black rectangle, //begin // but not at gridimage, but at TForm1, and I can't switch off it. canvas.pen.color:=clBlue; while vlines<width do begin canvas.line(vlines,0,vlines,height); inc(vlines,tilewidth); end; while hlines<height do begin canvas.line(0,hlines,width,hlines); inc(hlines,tileheight); end; //end; end;
解决方案
1. 初始化TImage时配置透明属性
创建gridimage时,开启透明并设置Bitmap支持alpha通道,同时清空画布为全透明:
procedure TForm1.gridButtonMouseUp(Sender: TObject; Button: TMouseButton; Shift: TShiftState; X, Y: Integer); var hlines,vlines: word; begin if showgrid then begin showgrid := false; if gridon then begin if Assigned(gridimage) then begin gridimage.Free; gridimage := nil; end; gridon := false; end; end else begin showgrid := true; if not gridon then begin gridimage := TImage.Create(terrainScrBox); gridimage.Parent := terrainScrBox; gridimage.Left := 0; gridimage.Top := 0; gridimage.Width := terrainCanvas.Width; gridimage.Height := terrainCanvas.Height; // 开启透明 gridimage.Transparent := True; // 设置Bitmap为带alpha通道的格式 gridimage.Picture.Bitmap.PixelFormat := pf32bit; gridimage.Picture.Bitmap.AlphaFormat := afPremultiplied; // 清空画布为全透明 gridimage.Picture.Bitmap.Canvas.Brush.Color := clNone; gridimage.Picture.Bitmap.Canvas.FillRect(Rect(0, 0, gridimage.Width, gridimage.Height)); griddrawing(gridimage); end; gridon := true; end; end;
2. 修正griddrawing过程的画布引用
明确使用传入TImage的Bitmap画布,同时设置画笔为透明,避免填充背景:
procedure TForm1.griddrawing(Sender: TObject); var hlines, vlines: word; img: TImage; begin if not (Sender is TImage) then Exit; img := TImage(Sender); vlines := tilewidth; hlines := tileheight; with img.Picture.Bitmap.Canvas do begin Pen.Color := clBlue; Brush.Color := clNone; // 画笔透明,仅绘制线条 while vlines < img.Width do begin Line(vlines, 0, vlines, img.Height); Inc(vlines, tilewidth); end; while hlines < img.Height do begin Line(0, hlines, img.Width, hlines); Inc(hlines, tileheight); end; end; img.Invalidate; // 刷新控件显示 end;
原理说明
- TImage默认Bitmap为
pf24bit格式,无alpha通道,绘制时会用黑色填充空白区域;设置为pf32bit并开启afPremultiplied后,支持全透明背景。 Brush.Color := clNone确保绘制线条时不会填充背景,仅保留蓝色线条。- 明确指定
img.Picture.Bitmap.Canvas,避免默认使用Form的画布,解决绘制位置错误问题。
内容的提问来源于stack exchange,提问作者Progizo
相关产品推荐
相关产品推荐

