Delphi、GR32 + PngObject:转换为 Bitmap32 无法按预期工作

2023-12-06

我正在使用 GR32 绘制多个半透明 PNG 图像。 到目前为止我一直在使用以下方法:

  png:= TPNGObject.Create;
  png.LoadFromFile(...);
  PaintBox321.Buffer.Canvas.Draw(120, 20, png);

但是我想切换到 GR32 网站上提出的方法(http://graphics32.org/wiki/FAQ/ImageFormatRelated) :

  tmp:= TBitmap32.Create;
  LoadPNGintoBitmap32(tmp, ..., foo);
  tmp.DrawMode:= dmBlend;
  PaintBox321.Buffer.Draw(Rect(20, 20, 20+ tmp.Width, 20+tmp.Height),
   tmp.ClipRect, tmp);

虽然第一种方法工作得很好,但第二种方法(应该给出相同的结果)会导致 alpha 通道出现非常奇怪的问题,请参见图像(它还显示了与 Paint.NET 中“排列”的相同图像的比较 - 背景和图标在编辑器的图层上打开)。该图像显示 Bitmap32 加载或绘制不正确。有小费吗?

Problem with TBitmap32 alpha channel

-- 11 月 22 日添加

我发现这不是关于绘图,而是关于将PNG加载到BMP32。从 BMP32 保存回 PNG 会生成不正确的“变白”(左侧)PNG 图像。


原因似乎是加载时透明度被应用到图像两次LoadPNGintoBitmap32,使其看起来更加透明和偏灰色(稍后会详细介绍)。

首先是透明度:

这是原始代码LoadPNGintoBitmap32,关键部分标有注释:

 PNGObject := TPngObject.Create;
 PNGObject.LoadFromStream(srcStream);

 destBitmap.Assign(PNGObject);  // <--- paint to destBitmap's canvas with transparency (!)
 destBitmap.ResetAlpha;         

 case PNGObject.TransparencyMode of  // <--- the following code sets the transparency again for the TBitmap32
 { ... }

The destBitmap.Assign内部的做法与之前的方法相同:它让 PNG 图像将自身绘制到画布上。此操作尊重 PNG 的 Alpha 通道。但这不是必需的,因为 alpha 通道已分配给TBitmap32第二步的像素!

现在将代码修改如下,关键部分再次标注注释:

 PNGObject := TPngObject.Create;
 PNGObject.LoadFromStream(srcStream);

 PNGObject.RemoveTransparency;  // <--- paint PNG without any transparency...
 destBitmap.Assign(PNGObject);  // <--- ...here
 destBitmap.ResetAlpha;

 srcStream.Position:=0;
 PNGObject.LoadFromStream(srcStream); // <--- read the image again to get the alpha channel back

 case PNGObject.TransparencyMode of   // <--- this is ok now, the alpha channel now only exists in the TBitmap32
 { ... }

上述解决方案效率低下,因为它读取了两次图像。但它说明了为什么第二种方法会产生更透明的图像。

对于灰色:原始代码中还有一个问题:destBitmap.Assign首先填充背景clWhite32,然后将图像透明地绘制到其上。进而LoadPNGintoBitmap32来并在其之上添加另一层透明度。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Delphi、GR32 + PngObject:转换为 Bitmap32 无法按预期工作 的相关文章

  • Delphi 2007 中的 HelpInsight 文档

    我正在使用 D2007 并尝试使用 HelpInsight 功能 自 D2005 起提供 来记录我的源代码 我主要对让 HelpInsight 工具提示正常工作感兴趣 通过各种网上冲浪和实验 我发现了以下内容 使用三斜杠 注释样式比其他记录
  • 如何将 JSON 字符串转换为图像?

    我有一个将图像转换为 JSON 数组的应用程序 并将其保存到 blob 字段中 function getImage String var memorystream TMemoryStream jsonArray TJSONArray beg
  • 如何追踪手柄泄漏?

    在我的一个应用程序中 我观察到句柄数量不断增加 在不使用应用程序的情况下 该数字大约每秒增加一次 因此后台处理代码的某些部分一定存在句柄泄漏 我如何追踪此类泄漏 有什么工具可以帮助解决这个问题吗 跟踪句柄泄漏时要寻找哪些模式 导致手柄泄漏的
  • Delphi中的抽象类

    我正在使用一个具有许多抽象类的组件套件 现在我想应用多态性 但在创建对象时收到错误抽象类 即使我不需要 我是否应该重写所有虚拟方法 有什么解决方法或解决方案吗 为了创建类的实例 您需要重写所有声明为虚拟抽象的方法 即使您不使用它们 如果您确
  • 在 Delphi 2009 上安装最新版本的 Indy 10 [重复]

    这个问题在这里已经有答案了 是否有更新 Delphi 2009 中的 Indy 10 组件的分步指南 我读过正在卸载线程 https stackoverflow com questions 486210 what is the proper
  • 在 Delphi 2007 中将具有透明度的位图保存为 PNG

    我有一个包含透明度信息的 Delphi 位图 32 位 我需要将其转换并保存为 PNG 文件 同时保留透明度 我目前拥有的工具是graphics32 Library GR32 PNG 由Christian Budde 提供 和PNGImag
  • 使用 TStringList 的分隔符解析字符串,似乎也解析空格(Delphi)

    我有一个简单的字符串 由某个字符分隔 比如说逗号 我应该能够创建一个 TStringList 并将其分隔符设置为逗号 然后将 DelimitedText 设置为我想要解析的文本 并且应该自动解析它 问题是 当我查看输出时 它还包含空格作为分
  • Delphi - 如何获取 USB 可移动硬盘和记忆棒的列表?

    在我的应用程序 Delphi 中 我需要列出所有 USB 存储设备 这些可以是闪存棒or外部存储驱动器 有一个Jvcl成分JvDriveCombo 并且它有DriveType属性 问题是我是否选择DriveType Fixed那么除了外部驱
  • 如何将数据库查询的行转换为 XML 文件?

    我正在开发一个 Delphi 应用程序 该应用程序需要从一段工作中获取行并将其转换为单个 XML 文件 以便上传到第三方 Web 服务 有没有可用的组件或库可以做到这一点 如果不是 那么构建 DB2XML 转换器的最佳代码方法是什么 我注意
  • 查找Delphi项目中的所有编译错误

    我正在对我的 Delphi 项目进行一些重构 我希望能够做出改变 然后看看all项目中因该更改而中断的地方 类似于 Eclipse 列出项目的所有编译错误 在 Java 中 在 Delphi 中 我可以进行更改 然后重新编译我的项目 但编译
  • 如何从 Delphi 中的函数返回对象而不导致访问冲突?

    我有一个返回 TStringList 的 delphi 函数 但是当我返回一个值并尝试使用它时 我收到一个访问冲突错误 即 myStringList FuncStringList myStringList Items Count lt Th
  • Delphi:写入后代类中私有祖先的字段

    我需要修复第三方组件 该组件的类具有私有变量 该变量由其后代主动使用 TThirdPartyComponentBase class private FSomeVar Integer public end TThirdPartyCompone
  • Delphi 2010 - 从 XML 文档解码 Base64 编码图像

    我正在尝试从应用程序中的 XML 文档解码 base64 编码的 EMF 图像并将其呈现在屏幕上 但是 它似乎从未出现 如果我将 XML 文档中的数据复制 粘贴到 Notepad 中并使用Base64 Decode选项并将文件另存为 emf
  • JavaFX:将像素写入 PixelWriter 的最快方法

    我正在寻找最快的方式来写入像素javafx scene image Image 写信给BufferedImage的后备数组要快得多 至少在我制作的测试图像上 只花了大约 20 毫秒BufferedImage WritableImage另一方
  • 适用于 .NET 2.0 的更精确的 PNG 库?

    是的 我正在使用 C 2 0 需要对 PNG 文件执行操作 例如使用自定义调色板 但我不知道如何使用 System Drawing 是否有第 3 方库 最好是兼容 GPL 的 可以对 PNG 编码进行更精细的控制 Update 我想做的事情
  • 如何使 QImage 或 QPixmap 半透明 - 或者为什么 setAlphaChannel 过时?

    4 7 并喜欢在 qgraphicsview 上叠加两个图像 顶部的图像应是半透明的 以便能够透过它看到 最初 两个图像都是完全不透明的 我期望存在一些为每个像素设置全局 alpha 值的函数 但似乎没有这样的函数 最接近的是 QPixma
  • Delphi XE7 Android 全屏(隐藏软键)

    如何在XE7中全屏显示 隐藏顶部 标题 和底部 软键 工具栏 在 XE6 中 我可以通过在应用程序部分写入来调整 AndroidManifest 以使我的应用程序全屏显示并且没有操作栏 android theme android style
  • Delphi 中表单分发与其生命周期相关的接口对象的安全方法?

    我有一个 Delphi 表单 它提供接口对象背后的功能 代码的其他部分也通过属于该表单的属性获取引用 我无法将接口功能委托给子对象 因为太多的功能是由表单上的控件 组件提供的 我无法使用 TAggregateObject 或 TContai
  • 使用 ImageMagick 和 PHP 将 PNG 转换为 JPG 并将透明背景设置为白色

    将图像从 PNG 转换为 JPEG 时 如何使用 ImageMagick 带有 php 扩展 将透明背景设置为白色 在撰写本文时 您尚未指定正在使用哪个扩展 但如果您使用命令行 则命令将是 convert image png backgro
  • 如果加载 dll 找不到依赖项,有什么方法可以捕获错误吗?

    我正在编写一个 Windows 32 位程序 可以使用多个可能的 dll 之一 所以它尝试依次加载每个 dll 使用SysUtils SafeLoadLibrary如果加载成功 它就会使用该 dll 不幸的是 其中一些 dll 静态链接到其

随机推荐

  • WebRTC:同时重新协商问题

    Use Case 三个同伴正在与同一房间中的另外两个同伴进行视频聊天 服务器发送一条消息 并且所有三个同伴都将模式更改为音频 目前 只有 chrome 支持重新协商 因此对于 firefox 我只需关闭连接并创建新的对等连接 但在我检查双方
  • Angular2 访问全局服务而不将其包含在每个构造函数中

    我有三门课 Injectable export class ApiService constructor public http Http get url string return http get url Injectable expo
  • 小叶杂食+聚类标记+过滤标记聚类组

    我尝试使用 Mapbox 和 Leafet 的杂食动物插件制作地图 以便通过教程搜索数据 我不知道如何在我的例子中集成来自杂食动物插件的代码 我使用 geojson url 作为我的数据 getJSON 用Leaflet的MarkerClu
  • 使用预测概率的插入符包中的自定义性能函数

    这个帖子是关于在中使用自定义性能测量函数caret包裹 您想要找到最佳的预测模型 因此您构建了多个预测模型 并通过计算通过比较观察值和预测值得出的单个指标来比较它们 有默认函数来计算此指标 但您也可以定义自己的指标函数 此自定义函数必须将观
  • 仅更改颤动中的数字字体系列

    我有一个完整的应用程序 并且正在使用自定义字体 有没有办法使用两种字体系列 一种用于文本 一种仅用于数字 请记住 API 中的文本和数字是混合的 下面是如何执行此操作的示例 我用了GoogleFonts用于获取不同的字体 但您可以将其替换为
  • 按住按钮不会触发单击

    我的 HTML5 应用程序中的按钮有问题 当我按下按钮时 视频播放器就会运行并播放本地存储的视频 我现在的问题是 当我按住按钮并释放它时 它不会启动视频播放器 我在按钮上使用 onclick 事件 我想要实现的目标是 如果我按住按钮然后释放
  • 在 shell 脚本中将十进制数转换为十六进制和二进制

    我在 a 的每一行都有一个十进制数file txt 1 2 3 我正在尝试 现在太久了 编写一个单行脚本来获得输出 其中每一行都有一列包含十进制 十六进制和二进制 为了简化任务 我们可以说原始数字以字节表示 所以最大值是 255 我首先尝试
  • 如何防止 Node.js 在等待回调时退出?

    我有这样的代码 var client new mysql Client options console log Icanhasclient client connect function err console log jannn acti
  • 为什么在 .net 2.0 中将 null 强制转换为原语(即 int)会引发 null 引用异常,而不是无效强制转换异常?

    我正在检查一些代码并遇到一个场景 其中我的组合框尚未初始化 这是在 NET 2 0 中 在以下代码中 this cbRegion SelectedValue 为 null int id int this cbRegion SelectedV
  • 显示/隐藏 DataGrid 列 XAML

    我正在尝试构建一个带有控件的 DataGrid 该控件允许用户显示 隐藏列 我的 DataGrid 将有大约 40 列 但并非所有列都始终是必需的 我已经能够使用使用 GridView 的 ListView 来完成这件事 这是代码
  • 嵌套模板,查找父级

    我有一系列嵌套对象 比如 商店和物品 我大概有 10 家商店 每家都有相同的 10 种商品 同时显示在屏幕上
  • 使用序列化 C++ 保存游戏状态

    我有一堂课叫Game其中包含以下内容 vector
  • 带有 jQ​​uery 弹出对话框的 ASP.NET:如何在对话框关闭时回发

    我正在开发一个相当复杂的网站 我们有一个包含一些控件的更新面板 单击其中一个控件时 将打开一个 jQuery 对话框 当对话框关闭时 我想通知更新面板更改其显示 为此 我需要发回更新面板 我知道该对话框有一个方便的回调事件 您可以连接到该事
  • 根据字符串匹配选择列 - dplyr::select

    我有一个包含很多很多列的数据框 数据 某些列包含特定字符串 search string 我该如何使用dplyr select 给我一个仅包含包含该字符串的列的子集 I tried columns as boolean vector sele
  • 使用外部函数获取用户定义函数返回的值表

    我是 R 的新手 试图理解向量处理方式而不是循环方式 我需要有关如何使用外部函数和用户定义函数创建值表的帮助 以下是一个简单的函数 给出了普通债券的价格 bp function y n 1 c 0 fv 100 freq 2 per 1 n
  • 混淆(minifyEnabled true)在调试和发布中均不起作用

    Android 混淆 minifyEnabled true 在调试和发布中均不起作用 minifyEnabled true 不适用于调试模式下的 android 我必须混淆我的 Android 项目 我已尝试过以下链接 但没有一个对我有用
  • Collat​​z 猜想:宽松的上限/下限? [关闭]

    Closed 这个问题是无关 目前不接受答案 这是我课本上的一道题 这科拉茨猜想 或 3n 1 问题 的工作原理如下 给定一些自然数n while n gt 1 do if n is even then n n 2 else n 3n 1
  • 如何在不停止的情况下将预览流添加到图表中?

    问题是构建一个支持三种状态的捕获图 仅预览 仅捕获为 AVI 文件 Combine 我已经建立了这样的图表 该图对应于状态 3 现在 如果我想更改状态 2 我会删除预览流并得到如下图 想象一下我运行图表并开始捕获 现在我想回到状态 3 如何
  • 如何在网格视图中添加空白行?

    我是 ASP NET 的新手 我正在将一个数据对象列表绑定到网格视图 我想在网格视图中的每条记录之后显示空白行 所以我通过下面的代码中完成了此操作 List
  • Delphi、GR32 + PngObject:转换为 Bitmap32 无法按预期工作

    我正在使用 GR32 绘制多个半透明 PNG 图像 到目前为止我一直在使用以下方法 png TPNGObject Create png LoadFromFile PaintBox321 Buffer Canvas Draw 120 20 p