Delphi 7中笔记本电脑上的Timage透明度

4

我想要做什么

我想将多个图形绘制到Timage上,这些图形由有序的层组成,包括填充和线条。我使用多个缓冲区来确保顺序和双缓冲。

我正在做什么

    procedure DrawScene();
var
  ObjLength,LineLength,Filllength,Obj,lin,angle,i:integer;
  Npoints : array[0..1] of Tpoint;
  Objmap:TBitmap;
  wholemap:TBitmap;

begin
  wholemap := TBitmap.Create;
  wholemap.Width:=area;
  wholemap.height:=area;

  ObjLength:=length(Objects);
  for Obj:=0 to (ObjLength-1) do
  if objects[Obj].Visible then
  begin
    // create object bitmap

    if Objects[obj].Tag='FBOX' then
      begin

      Objmap := TBitmap.Create;
      Objmap.Width:=area;
      Objmap.height:=area;
      Objmap.Transparent:=true;

      Objmap.Canvas.Rectangle((objects[obj].Boundleft-4)+objects[obj].Position.x,area-((objects[obj].boundtop+4)+objects[obj].Position.y),(objects[obj].boundright+4)+objects[obj].Position.x,area-((objects[obj].boundbottom-4)+objects[obj].Position.y));
      end;
    //draw object
    LineLength:=length(objects[Obj].Lines)-1;
    angle:=objects[Obj].Rotation;
    for lin:=0 to (LineLength) do
    begin
      for i:=0 to 1 do
      begin
        Npoints[i] := PointAddition(RotatePoint(objects[obj].Lines[lin].Point[i],angle),objects[obj].Position,false);
      end;
      Objmap:=DrawLine(Npoints[0].x,Npoints[0].y,Npoints[1].x,Npoints[1].y,objects[obj].Lines[lin].Color,Objmap);
    end;


    Filllength:=length(objects[Obj].Fills)-1;
    for i:=0 to Filllength do
      begin
        Npoints[0]:=PointAddition(RotatePoint(objects[Obj].Fills[i].Point,objects[Obj].Rotation),objects[Obj].Position,false);
        Objmap:=fillpoint( Npoints[0].x, Npoints[0].y,objects[Obj].Fills[i].color,Objmap);
      end;

      //write object to step frame
      wholemap.Canvas.Draw(0,0,Objmap);
      Objmap.Free;


  end;
   // write step frame to Visible Canvas
   mainwindow.bufferim.Canvas.Draw(0,0,wholemap);
   mainwindow.RobotArea.Picture.Graphic:=mainwindow.bufferim.Picture.Graphic;


   wholemap.Free;

end;

我期望的结果

我希望看到每个图像对象层叠在一起,每个图像层都是该层的完整图像。例如,在我的例子中,有一个机器人和一个在其后面的旗帜。首先绘制旗帜,然后再绘制机器人。

在电脑上实际得到的结果

在电脑上,我得到了我期望的结果,所有内容都正确显示。

在笔记本电脑上实际得到的结果

在几乎所有笔记本电脑和一些台式电脑上,我只能看到机器人。我添加了一些语句来查看是否正在绘制旗帜,它确实在绘制旗帜。游戏甚至可以以正确的方式与旗帜交互。进一步调查显示,它只显示了“drawscene”中绘制的最后一个图像,当直接将图像绘制到wholecanvas时,一切都正常(由于重叠填充层的原因,这不能做到)。

我认为发生了什么事情

所以我推断出Timage.transparent属性在某些计算机上不起作用或被计算机以不同方式处理。

我进行了测试以证明这一点,并使画布变为红色。然后在0,0处绘制了一个Timage,其属性为transparent=true,中间只有一个点。结果是一个白色画布,中间有一个点。

我的假设和发现表明,具有非常基本图形驱动程序的计算机似乎将null或透明视为白色,而更强大的计算机似乎将null或透明视为透明。

由于Timage.Transparent属性为true,这似乎有点失败。

编辑: 更新!!! 看起来,在ATI显卡上,如果颜色为“null”,则它会以PF24bit格式解释,因此没有alpha通道和透明度。

在Nvidia卡上,它将其作为PF32bit,并将null视为透明。
显然,解决这个问题的方法是将位图类型设置为PF32bit,但仍然不起作用。 然后我认为,也许这还不够,我应该确保背景被设置为透明而不是被留为空..但是,在Timage内部没有工具(我能看到的)可以使用带有Alpha的颜色进行设置。所有画布绘制函数都需要一个RGB 24位的Tcolor,只有RGBA 32位的TcolorRef才能实现.. 有没有一种方法可以使用alpha 0进行绘制?

我认为我需要知道的信息

如何强制Transparent属性在所有计算机上起作用 或使笔记本电脑不将透明粘贴为白色 或实现相同的结果。

有人有任何解决方案或想法吗?


1
无论是笔记本还是台式电脑本身并不重要,但屏幕分辨率和尤其是色彩深度可能很重要。您能够检查这些内容吗?至少在两台机器上进行检查,一台可以运行,另一台不能运行。 - Pekka
另一个可能的问题是:您笔记本电脑的屏幕可能无法显示您的颜色(例如:所有颜色的非常浅的色调),因此对您来说,“透明度”功能似乎不起作用,而实际上它正在工作,但您没有看到它。 大多数投影仪也会出现这种情况。 如何测试:在PC上截屏应用程序,保存为位图,将位图复制到笔记本电脑。 或者反过来,在笔记本电脑上截屏并在PC上检查位图。 - Cosmin Prund
3个回答

2

我曾在过去几年的不同机器上看到类似的行为。

它们是由不同的显卡和驱动程序引起的。NVIDIA或ATI其中之一会得到错误的结果,但我忘记了哪一个。

它可以在笔记本电脑和常规PC上重现。

所以:您使用什么显卡和驱动程序?

--jeroen


这似乎是个问题。经过调查,一些颜色深度与正常工作机器相同的机器无法工作,并且它无法显示的颜色包括白底黑字。但是当我查看视频驱动程序时,我发现所有正常工作的机器都有 Nvidia 驱动程序/显卡,而所有不能正常工作的机器都有 ATI。是否有任何方法让它们工作? - Arthur
@Arthur:当时我没有找到解决方案使其正常工作。但后来客户放弃了基于ATI的机器,问题自然而然地解决了。 - Jeroen Wiert Pluimers

2

我一直在使用一个图形库(AggPas)来帮助进行图形绘制,其中一个我注意到的问题是,我总需要一条线 Bitmap.PixelFormat = pf32bit 才能使其绘制透明度。

话虽如此,我使用 AggPas 库中的 TransformImage 将具有透明背景的图像复制到另一个图像中,而 AggPas 只接受 pf24bit 或 pf32bits 作为像素格式(否则它不能附加到位图上)。


1

我建议您在创建每个位图时明确设置位图格式为pf32bit,以确保不会从32位转换为16位(如果正在创建的位图的本机视频分辨率为16位),这可能会干扰透明度的工作方式。此外,过去我在特别设置透明颜色方面取得了更好的效果。

另一个选择 - 或许是长远来看更好的选择,是在图像上设置Alpha通道(即使用PNG文件),并使用GDI函数AlphaBlend()绘制图形。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接