最近

作者主题:Linux中的破碎示例“为TImage创建和绘制透明位图”(阅读5327次)

吉佩特

  • 正式成员
  • ***
  • 职位:178
Linux中的破碎示例“为TImage创建和绘制透明位图”
«日期:2024年5月23日上午08:39:16»
你好,

运行Linux-Debian 12.5 64位gtk2计算机,如果我试试这个例子https://wiki.freepascal.org/Developing_with_Graphics#Creating_and_drawing_a_transparent_bitmap_for_a_TImage使用Copy-and-Paste,由于Image1.Transparent to True的设置,我得到的唯一显示是TImage中没有任何内容(请在示例上方读3行)。
如果设置为False,则TImage为黑色。
有人告诉我,同样的例子在Windows中也能很好地工作:参见img

小提示:我添加了两行:
代码:Pascal[选择][+][-]
  1. ...
  2.    国际货币基金组织 :=骨形成蛋白.创建IntfImage;
  3.    如果骨形成蛋白.像素格式 =pf32位然后解说词:= “确定32”; //添加了行,看到了单词
  4. ...
  5.      最后
  6. 中央电视台.免费;
  7.      结束;
  8. 骨形成蛋白.从国际图像加载(国际货币基金组织);
  9.      如果骨形成蛋白.像素格式 =pf32位然后显示消息(“确定32”); //行已添加,消息未显示
  10. ...
  11.  

另一个帮助bmp。保存到文件('a_path')显示黑色位图。

非常感谢你的帮助。
«最后一次编辑:2024年5月23日下午06:46:10 jipété»

水处理

  • 英雄会员
  • *****
  • 职位:12314
在gtk2、gtk3和qt5上重新测试:样品工作正常(除了gtk3中交换红色和蓝色通道,但这是另一个问题)。

由于Image1.Transparent to True的设置,我得到的唯一显示是TImage中没有任何内容(请阅读示例上方的3行)。
如果设置为False,则TImage为黑色。
对不起,这是这篇文章历史悠久的左撇子。。。添加了一些澄清说明。复制和粘贴的代码不使用图像。透明属性(不是100%确定,但我甚至建议在本例中关闭它)。图像。透明是一个控制“颜色透明度”的属性,其中一种特定颜色被声明为透明且不绘制。

吉佩特

  • 正式成员
  • ***
  • 职位:178
关于:Linux中的破解示例“为TImage创建和绘制透明位图”
«回复#2时间:2024年5月23日,07:23:31 pm»
你好!

在gtk2、gtk3和qt5上重新测试:样品工作正常
用Red-Hat?Ubuntu?苏西?其他?

复制和粘贴的代码不使用图像。透明属性(不是100%确定,但我甚至建议在本例中关闭它)。
我反复尝试过,从来没有看到过漂亮的彩色图像,除了在我的测试开始时(三四天前)有一次,通过随意地改变这里和那里的东西,我得到了漂亮的图像,但当我开始感到疲倦时,我没有想过制作图像和代码的屏幕截图,真是遗憾。。。

非常感谢我在另一篇帖子中的错误报告。

手册

  • 英雄会员
  • *****
  • 职位:5290
  • 我的目标:使用Lazarus构建我自己的游戏引擎
我使用Lazarus 3.0 64位在Ubuntu Mate 23.10 GTK2上测试了代码。“ok 32”消息被触发。查看上的结果屏幕截图.png如下所示。

我唯一不能让它工作的是,保存的bmp不支持透明度。请参阅保存的图像.png如下所示。(为了减小文件大小,我将bmp转换为png)

这是我使用的代码:

代码:Pascal[选择][+][-]
  1. 单元1号机组;
  2.  
  3. {$mode objfpc}{$H+}
  4.  
  5. 接口
  6.  
  7. 使用
  8. 课程,形式,绘图,标准Ctrls,fp图像,fpCanvas(fp画布),国际图形,ExtCtrls(外部控制),
  9. LazCanvas公司,对话框;
  10.  
  11. 类型
  12.  
  13.  {T形式1}
  14.  
  15. T形1=(T表格)
  16. 按钮1:按钮控件;
  17. 图像1:TImage公司;
  18.    程序按钮1单击(发件人:TObject(目标));
  19.  结束;
  20.  
  21. 无功功率,无功功率
  22. 表格1:T形1;
  23.  
  24. 实施
  25.  
  26. {$R*.lfm}
  27.  
  28. {TForm1}
  29.  
  30. 程序T形1.按钮1单击(发件人:TObject(目标));
  31. 无功功率,无功功率
  32. 骨形成蛋白:TBit地图;
  33. 国际货币基金组织:TLazIntf图像;
  34. 中央电视台:TLazCanvas公司;
  35. 开始
  36. 骨形成蛋白:=TBit地图.创建;
  37.  尝试
  38. 骨形成蛋白.像素格式 :=pf32位;         //重要!
  39. 骨形成蛋白.设置大小(图像1.宽度,图像1.高度);
  40. 骨形成蛋白.透明 := 真的;
  41. 骨形成蛋白.透明色 :=cl黑色;
  42. 骨形成蛋白.清除;
  43. 骨形成蛋白.透明色 :=cl黑色;
  44. 骨形成蛋白.透明 := 真的;
  45. 国际货币基金组织:=骨形成蛋白.创建IntfImage;
  46.    尝试
  47. 中央电视台:=TLazCanvas公司.创建(国际货币基金组织);
  48.      尝试
  49. 中央电视台.绘图模式 :=dmAlphaBlend(dmAlpha混合); //这将激活alpha混合模式。
  50.  
  51.        //背景
  52. 中央电视台..样式 :=ps清除;
  53. 中央电视台.刷子.FP颜色 :=colTransparent(透明色);
  54. 中央电视台.FillRect(填充矩形)(0, 0,国际货币基金组织.宽度,国际货币基金组织.高度);
  55.  
  56.        //黄色不透明矩形
  57. 中央电视台.刷子.FP颜色 :=FP颜色(美元FFFF, 美元FFFF, 0);
  58. 中央电视台.矩形(10, 10, 190, 100);
  59.  
  60.        //重叠的半透明红色圆圈
  61. 中央电视台.刷子.FP颜色 :=FP颜色(美元FFFF, 0, 0, $4000);
  62. 中央电视台.椭圆(60, 60, 140, 140);
  63.  
  64.        //重叠半透明蓝色圆圈
  65. 中央电视台.刷子.FP颜色 :=FP颜色(0, 0, 美元FFFF, $8000);
  66. 中央电视台.椭圆(0, 100, 100, 200);
  67.      最后
  68. 中央电视台.免费;
  69.      结束;
  70.  
  71. 骨形成蛋白.从IntfImage加载(国际货币基金组织);
  72.      如果骨形成蛋白.像素格式 =pf32位然后显示消息(“确定32”);
  73. 骨形成蛋白.保存到文件('测试.bmp');
  74. 图片1.图片.分配(骨形成蛋白);
  75.    最后
  76. 国际货币基金组织.免费;
  77.    结束;
  78.  最后
  79. bmp格式.免费;
  80.  结束;
  81. 结束;
  82.  
  83. 结束.

如果你想帮助任何人,请下载代码,运行它并报告你的测试结果。
«上次编辑:2024年5月23日08:10:04 pm Handoko»

弗雷德vS

  • 英雄会员
  • *****
  • 职位:3314
    • StrumPract是音乐家最好的朋友
我使用Lazarus 3.0 64位在Ubuntu Mate 23.10 GTK2上测试了代码。“ok 32”消息被触发。查看上的结果屏幕截图.png如下所示。

我唯一不能让它工作的是,保存的bmp不支持透明度。请参阅保存的图像.png如下所示。(为了减小文件大小,我将bmp转换为png)

这是我使用的代码:
...
如果你想帮助任何人,请下载代码,运行它并报告你的测试结果。

你好,Handoko。

Xubuntu 22.04 x86_64上。

在您的代码中,添加此项将提供测试2.png具有透明度(但仅限于png公司文件夹,骨形成蛋白afaik不是透明事物的拥护者)。
但奇怪的是测试.png没有透明度。
 
代码:Pascal[选择][+][-]
  1.    ....
  2.      骨形成蛋白.从IntfImage加载(国际货币基金组织);
  3.      如果骨形成蛋白.像素格式 =pf32位然后显示消息(“确定32”);
  4. bmp格式.保存到文件('测试.png');
  5. 图片1.图片.分配(骨形成蛋白);
  6. 图像1.图片.保存到文件('测试2.png'); //添加此选项可提高透明度
  7.      ....

«上次编辑:2024年5月23日,08:52:58 pm,Fred vS»
我在Debian 11 64位、Windows 10、Windows 7 32/64、Windows XP 32、FreeBSD 64上使用Lazarus 2.2.0 32/64和FPC 3.2.2 32/64。
小工具集:fpGUI、MSEgui、Win32、GTK2、Qt。

https://github.com/fredvs网址
https://gitlab.com/fredvs网址
https://codeberg.org/fredvs网站

水处理

  • 英雄会员
  • *****
  • 职位:12314
用Red-Hat?Ubuntu?苏西?其他?
真是一团糟。。。最初的测试是使用Mint/Laz-main/FPC3.2.2进行的,gtk2、qt5(和gtk3除外,红蓝订单除外)都很好。

然后,我切换到Manjaro:gtk2-报告中的黑色图像,但:qt5-ok,gtk3-“半ok”与红色-蓝色进行了交换。

Manjaro/gtk2中的更多实验:
  • 在创建intfimage之前用白色填充位图->我看到了预期的图像,但背景是白色的。当我保持位图不变,但将IntfImg的背景色设置为colWhite=($FFFF,FFFF、FFFF和FFFF)时,会返回相同的图像。当我将alpha通道(最后一个$FFFF)设置为0时,背景变黑,但圆和矩形仍然可见。
  • 取下之前实验中的代码,我切换了图像。将透明属性设置为true。现在,图像变成了“彩色透明”——前一张图像中所有黑色的东西都变成了透明的。好 啊?不,因为半透明圆圈重叠的区域下面仍然是黑色背景,看起来太暗了。
  • 知道使用alpha通道可以正确显示png文件,我将生成的图像写入流并将其读回-结果相同:黑色背景中嵌入了圆形和矩形。

吉佩特

  • 正式成员
  • ***
  • 职位:178
你好,

@手册:使用复制/粘贴代码,
如果Image1.Transparent设置为True,则表单上不会显示任何内容;
如果Image1.Transparent设置为False,则显示黑色。
在这两种情况下,test.bmp都是黑色的。

@弗雷德:加上你的台词,
如果Image1.Transparent设置为True,则表单上不会显示任何内容;
如果Image1.Transparent设置为False,则显示黑色。
在这两种情况下,test2.png都是黑色的。

@工作包:
>>>在创建intfimage之前用白色填充位图
我很乐意阅读你的代码,只是为了确保我也能像你一样做。

无论如何,这个故事变成了噩梦...
也许我的电脑出了问题,但怎么了?哪里?
再见,谢谢你的帮助。

萨迪

  • 英雄会员
  • *****
  • 职位:15557
  • 对意见的审查不属于这里。
可能是因为标题栏的圆角边缘,拾取了错误的透明度像素吗?因为那个角落是黑色的!
如果我闻到坏代码的味道,通常是坏代码,这包括我自己的代码。

水处理

  • 英雄会员
  • *****
  • 职位:12314
关于:Linux中“为TImage创建和绘制透明位图”的坏例子
«回复#8:2024年5月24日上午11:14:26»
@工作压力:
>>>在创建intfimage之前用白色填充位图
我很乐意阅读你的代码,只是为了确保我也能像你一样做。
我正在附加一个完整的项目,准备编译,以便您可以轻松测试。它带有gtk2、gtk3、qt5和预先选择的窗口、gtk2的构建模式。它以两种方式创建维基文章的字母混合图像:
  • 按钮“Create image as LazIntfImage”与TLazIntfImage一起工作,就像在wiki中一样。如前所述,这在所有小部件集中都能正常工作,但gtk2除外,在gtk2中,整个图像变为黑色(现在我的Mint-VM上也会出现这种情况-奇怪…)。选中“使用白色背景”复选框后,黑色消失,但可以在白色背景上看到图形。
  • “将图像创建为FPImage”按钮使用必须基本的fcl图像库创建字母混合图形。由于这不能直接显示在TImage中(至少据我所知),我将图像保存到一个临时流中,并让TImage从中加载图像-现在结果是正确的,即使在gtk2上也是如此! 
我认为gtk2中的TLazIntfImage有问题。它肯定不是你的硬件。

[编辑]
提交错误报告:https://gitlab.com/freepascal.org/azarus/lazarus/-/issues/40971
«上次编辑时间:2024年5月24日12:43:03 pm wp»

吉佩特

  • 正式成员
  • ***
  • 职位:178
我认为gtk2中的TLazIntfImage有问题。它肯定不是你的硬件。
哦,你的项目太棒了!

与FPimage配合使用非常好,谢谢谢谢谢谢!
(稍后提供图片和更多评论…)

吉佩特

  • 正式成员
  • ***
  • 职位:178
关于:Linux中“为TImage创建和绘制透明位图”的坏例子
«回复#10:2024年5月24日,07:43:59 pm»
大家好!

好了,没什么可说的,只需用Debian/Gtk2显示我的结果:

使用LazIntfImage,黑色窗口:
懒惰图片.png

使用LazIntfImage和白色背景,这很好:
LazIntfImage+white_bkg.png

使用FPImage,无论有无白色背景,都能获得同样的效果:
FP图像.png

但是(因为总是有一个“But”)我注意到了一个小的舍入错误,我想:比较一下蓝色圆圈的底部,从LazIntfImage的左侧和圆形,从FPImage的右侧和平面。。。
小环绕错误.png参见下文:D

如果我尝试以下片段,圆圈的底部就可以了;
代码:Pascal[选择][+][-]
  1.    //重叠半透明蓝色圆圈
  2. 坎弗.刷子.FP颜色 :=FP颜色(0, 0, 美元FFFF, $8000);
  3. //坎弗。椭圆(0,100,100,200);
  4. 坎弗.椭圆(0, 100, 100, 199);
(由于论坛限制,我无法发布显示修正后舍入错误的第五张图片,抱歉,请自行尝试)
一个文件中有两个图像:P:
little_rounding_error+error_corrected.png
在左边,上面的删除线文本,在右边,左边的图像是用Bottom@200制作的,右边的图像是使用Bottom@199制作的。

再次感谢您抽出宝贵时间。
下一步,学习FPImage!
«上次编辑:2024年5月24日,下午07:50:25,jipété»

水处理

  • 英雄会员
  • *****
  • 职位:12314
啊,我认为这是由于两个绘图程序中存在微小的不一致:

下部按钮将TFPMemoryImage创建为200x200像素;由于下面的圆圈精确到200,因此有点不清楚y=200的像素是否被绘制出来(图形中的老问题)搜索论坛,最近对此进行了讨论。显然,这里没有绘制最后一个像素行。

另一方面,上面的按钮创建的TLazIntfImages与TImage组件一样大——这比200x200大得多!因此,可以确定绘制较低的像素行。

请更改代码,使上面的图像也是200x200像素,您将在两个图像中看到相同的剪切效果。

水处理

  • 英雄会员
  • *****
  • 职位:12314
  • “将图像创建为FPImage”按钮使用必须基本的fcl图像库创建字母混合图形。由于这不能直接显示在TImage中(至少据我所知),我将图像保存到一个临时流中,并让TImage从中加载图像
当然,这种说法是不正确的。。。FPImage可以分配给TImage的Picture属性,并在TImage中显示,而无需临时流:
代码:Pascal[选择][+][-]
  1. 程序T形1.按钮2单击(发件人:TObject(目标));
  2. 无功功率,无功功率
  3. 国际货币基金组织:TFP内存映像;
  4. 坎弗:TFPImage画布;
  5. 开始
  6. 国际货币基金组织:=TFP内存映像.创建(200, 200);
  7. 坎弗:=TFPImage画布.创建(国际货币基金组织);
  8.  尝试
  9. 坎弗.绘图模式 :=dmAlphaBlend(dmAlpha混合); //这将激活alpha混合模式
  10.  
  11.    //背景
  12. canv公司..样式 :=ps清除;
  13. 坎弗.刷子.FP颜色 :=colTransparent(透明色);
  14. 坎弗.FillRect(填充矩形)(0, 0,国际货币基金组织.宽度,国际货币基金组织.高度);
  15.  
  16.    //黄色不透明矩形
  17. 坎弗.刷子.FP颜色 :=FP颜色(美元FFFF, 美元FFFF, 0);
  18. 坎弗.矩形(10, 10, 190, 100);
  19.  
  20.    //重叠的半透明红色圆圈
  21. 坎弗.刷子.FP颜色 :=FP颜色(美元FFFF, 0, 0, $4000);
  22. 坎弗.椭圆(60, 60, 140, 140);
  23.  
  24.    //重叠半透明蓝色圆圈
  25. 坎弗.刷子.FP颜色 :=FP颜色(0, 0, 美元FFFF, $8000);
  26. 坎弗.椭圆(0, 100, 100, 200);
  27.  
  28.    //显示图像
  29. 图像1.图片.分配(国际货币基金组织);
  30.  最后
  31. 坎弗.免费;
  32. 国际货币基金组织.免费;
  33.  结束;
  34. 结束;

吉佩特

  • 正式成员
  • ***
  • 职位:178
FPImage可以分配给TImage的Picture属性,并在TImage中显示,而无需临时流:
不在这里!
我仍然有黑色背景。。。

要查看漂亮的显示,(对我来说)唯一的方法是使用流:
代码:Pascal[选择][+][-]
  1.    ...
  2.    流动 :=TMemoryStream(内存流).创建;
  3. 作家:=TFP编写器PNG.创建;
  4.    尝试
  5. 作家.使用Alpha := 真的; //确保alpha通道未被丢弃。
  6. 国际货币基金组织.保存到流(流动,作家);
  7.      //保存到图像文件
  8. 国际货币基金组织.保存到文件(“Transp_with-stream.png”); //黑色背景!
  9. 溪流.职位 := 0;
  10. 图像1.图片.从流加载(流动); //没有背景,很好!
  11. 图像1.图片.保存到文件(“Transp_Picture.png”); //也可以
  12.    最后
  13. 作家.免费;
  14. 溪流.免费;
  15.    结束;
  16.  最后
  17. 坎弗.免费;
  18. 国际货币基金组织.免费;
  19.  结束;
  20. 结束;
我发现了一个陷阱:我们必须查看一个图像编辑器(Gimp或其他),因为如果在FileExplorer中查看图像,则无法区分白色背景和透明背景。
研究我在FileExplorer中显示的两幅图像:一幅上面是白色背景,另一幅下面是透明背景。
白色-棕色

并与the Gimp中的相同文件进行比较
比较经典流.png

又是一场噩梦。。。

水处理

  • 英雄会员
  • *****
  • 职位:12314
FPImage可以分配给TImage的Picture属性,并在TImage中显示,而无需临时流:
不在这里!
我仍然有黑色背景。。。
对不起,我被另一个线程弄糊涂了(对于我有限的大脑来说,不同的线程太多了……)。你完全正确。

我发现了一个陷阱:我们必须查看一个图像编辑器(Gimp或其他),因为如果在FileExplorer中查看图像,则无法区分白色背景和透明背景。
研究我在FileExplorer中显示的两幅图像:一幅上面是白色背景,另一幅下面是透明背景。
白色-棕色

并与the Gimp中的相同文件进行比较
比较经典流.png
好吧,当Gimp显示字母通道图像的复选框背景时,您肯定知道字母通道和透明度存在并且是正确的。当其他程序显示白色背景时,这不是图像的问题。

又一场噩梦。。。
我不会称之为“噩梦”。只需做好准备,图像的透明度可能有点难以检测。我的默认图像查看器,例如IrfanView;我将它的背景设置为一些不寻常的颜色;有了这一点,我就不太可能被透明度的存在愚弄了。

 

TinyPortal公司 © 2005-2018