Delphi 7 笔记本电脑上的 Timage 透明胶片

发布于 2024-09-09 09:57:15 字数 3176 浏览 1 评论 0原文

我正在尝试做什么

我正在尝试将多个图形绘制到 Timage,我绘制的这些图形由带有 Foodfills 和线条的有序图层组成。 我使用多个缓冲区来确保排序和双缓冲。

我正在做什么

    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;

我期望什么

我期望看到每个图像对象层叠在另一个之上,每个图像层都是该层的完整图像。 我的例子是一个机器人,后面有一面旗帜。 首先绘制旗帜,然后绘制机器人。

我得到什么(在电脑上)

在电脑上我得到了我所期望的,并且一切似乎都是正确的。

我得到了什么(在笔记本电脑上)

在几乎所有笔记本电脑和某些电脑上,我只看到机器人。 我输入了一些语句来查看它是否正在绘制旗帜,并且确实如此。游戏甚至可以以正确的方式与旗帜互动。 进一步的调查表明,它只显示了我的“绘图场景”中绘制的最后一个图像,并且当图像直接绘制到整个画布时,所有内容都出现了(由于重叠填充层的原因,这无法完成)

我认为发生了什么

我推断 Timage 的 Timage.transparent 属性不起作用或者在某些机器上计算方式不同。

我做了一个测试来证明这一点并将画布设为红色。然后到我在 0,0 i Timage 处绘制的画布,属性透明=true,红色画布中间只有一个点。结果是一张白色的画布,中间有一个点。

我假设和研究结果表明,具有非常基本的图形驱动程序的机器似乎将空或透明视为白色,而更强大的机器似乎将空或透明视为透明。

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

编辑: 更新!!! 在 ATI 显卡上,如果颜色为“空”,则它会以 PF24 位格式进行解释,因此没有 Alpha 通道,也没有透明度。

在 Nvidia 卡上,它将其视为 PF32bit 并将 null 视为透明。

解决这个问题的明显方法是将位图类型设置为 PF32bit,但这仍然不起作用。 然后我假设这可能还不够,我应该确保背景设置为透明而不是保留为空..但是 Timage 内部没有工具(我可以看到)来使用 alpha 设置颜色。所有画布绘图函数都需要 RGB 24 位的 Tcolor,只有 RGBA 32 位的 TcolorRef 才可以...... 有没有办法用 alpha 0 绘图?

我认为我需要知道

如何强制透明属性在所有机器上工作 或者一种使笔记本电脑不粘贴为透明白色的方法 或者达到相同结果的方法。

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

WHAT I AM TRYING TO DO

I am trying to draw multiple graphics to a Timage, These graphics that i Draw consist of ordered layers with Foodfills and lines.
I use multiple buffers to ensure ordering and double buffering.

WHAT I AM DOING

    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;

WHAT I EXPECT

I expect to see each image object layered on top of one another with each image layer being the complete image for that layer.
im my example it is a robot with a flag behind it.
the flag is drawn first and then the robot.

WHAT I GET(on a pc)

on a pc i get what i expect and all appears to be correct.

WHAT I GET(on a laptop)

On a nearly every laptop and some pc's i only see the robot.
i put in some statments to see if it is drawing the flag and it does. the game can even interact with the flag in the correct manner.
further investigation showed me that it was only showing the last image drawn my "drawscene", and when images were drawn directly to the wholecanvas everthing apeared(this cannot be done for overlapping fill layers reasons)

WHAT I THINK IS HAPPENING

so what i deduced is that the Timage.transparent property of the Timage is not working or is being computed differently on some machines..

i did a test to prove this and made a canvas red. then to that canvas i drew at 0,0 i Timage with property transparent=true with just one dot in the middle to the red canvas. the resuly was a white canvas with a dot in the middle.

I am assuming and findings indicate that machines with very basic graphics drivers seem to treat null or transparent as white where as more powerful machines seem to treat null or transparent as transparent.

this seems to be a bit of a failure due to the fact that the Timage.Transparent property was true.

EDIT:
UPDATE!!!
It would appear to be that on ATI graphics cards if a colour is "null" then it is interpreted in the format of PF24bit and therefore no alpha channel and no transparency.

on Nvidia cards it takes it as PF32bit and treats null as transparent.

the obvious way to get around that woulf be to set the bitmaptype to PF32bit, but that does still not work.
I then assumed that maybe that is not enough and I should make sure that the background is SET to transparent rather than being left as null.. but there are no tools ( that I can see) inside the Timage to set colour with alpha. all canvas drawing functions require a Tcolor that is RGB 24 bit and ony a TcolorRef with RGBA 32 bit would do....
is there a way of drawing with alpha 0?

WHAT I THINK I NEED TO KNOW

How to force the Transparent property to work on all machines
or a way to make laptops not paste in transparent as white
Or a way to achieve the same result.

Anyone have any solutions or ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

羞稚 2024-09-16 09:57:15

我一直在使用图形库(AggPas)来帮助绘制图形,我注意到的一件事是我总是需要一行 Bitmap.PixelFormat = pf32bit 来让它绘制透明度。

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

I have been using an Graphics library (AggPas) to help with drawing graphics and one of the things I've noticed is that I always need a line Bitmap.PixelFormat = pf32bit to get it to draw transparancies.

Having said that I use TransformImage from the AggPas library to copy the Image with a transparent background to another one and AggPas only accepts pf24bit or pf32bits as Pixel formats (otherwise it doesn't attach to the bitmap)

各自安好 2024-09-16 09:57:15

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

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

它可以在笔记本电脑和普通 PC 上复制。

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

——杰罗恩

I've seen similar behaviour on different machines in the past (a few years back).

They were caused by different video cards and drivers.
Either the NVideo or the ATI ones were getting the wrong results, but I forgot which ones.

It could be reproduced on both laptops and regular PC's.

So: what video cards and drivers do you use?

--jeroen

递刀给你 2024-09-16 09:57:15

我会为您创建的每个位图明确将位图格式设置为 pf32bit,以确保问题不是将颜色从 32 位转换为 16 位(如果这是创建位图的本机视频分辨率),这可能会干扰透明度的工作方式。另外,我过去专门设置透明度颜色的运气更好。

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

I would explicitly set the bitmap format to pf32bit for each bitmap you create to ensure the problem isnt converting colors from 32 to 16 bit (if thats the native video resolution of the bitmaps getting created), which might interfere with how the transparency works. Also, I've had better luck specifically setting the transparency color in the past.

Another option - perhaps a better one in the long run, is to instead set the Alpha Channel on the images (ie, use PNG files), and use the GDI function AlphaBlend() to draw the graphics.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文