You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何隐藏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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.24 21:00:41