为什么当 Alpha==0 时 System.Drawing.Graphics 会清空 RGB 通道?

2024-04-03

这已经成为我正在开发的处理具有 Alpha 通道的图像的程序的严重障碍。 我拥有的许多图像都包含颜色信息,其中 Alpha 通道是完全透明的,但是一旦我尝试将它们加载到 System.Drawing.Graphics 中,它就会将 Alpha 为 0 的任何内容更改为 Alpha 为 0 的黑色。

这是该问题的基本示例。 我环顾四周试图找到原因、答案或解决方法,但我还没有找到任何暗示这个问题的东西。Any此时,我们将不胜感激。

var myTestTransparentColor = Color.FromArgb(0, 255, 128, 64);
var image = new Bitmap(135, 135, PixelFormat.Format32bppArgb);

using (var g = Graphics.FromImage(image))
{
    g.Clear(myTestTransparentColor);
}

var color = image.GetPixel(0, 0);

Debug.Assert(color == myTestTransparentColor, "channels must match original");

EDIT:

经过进一步的测试后,我并没有真正看到使用 System.Drawing.Graphics 的出路,所以我唯一的解决方案(不是真正的答案)是完全避免 System.Drawing.Graphics 。看看我的代码,看起来我可以避免它。 就在使用 System.Drawing.Graphics 绘制形状、在图像上植入文本多年之后,我发现 System.Drawing.Graphics 出现这样的重大缺陷很令人恼火。

我仍然想知道我是否可以使用 System.Drawing.Graphics 并保持我的 ARGB 完好无损,但我想我现在可以没有它。


我认为 Vincent Povirk 在这里恰当地回答了我的问题:使用 GDI+ 绘制 PixelFormat32bppPARGB 图像使用传统公式而不是预乘公式 https://stackoverflow.com/questions/19809506/drawing-pixelformat32bpppargb-images-with-gdi-uses-conventional-formula-instead

“前景图像的格式并不重要(假设它有 alpha),因为您将其设置为 Gdiplus::Color。颜色值被定义为非预乘,因此 gdiplus 在以下情况下将分量乘以 alpha 值:它会清除前景图像。另一种选择是颜色值根据渲染目标的格式具有不同的含义,这就是疯狂。”

“如果您确实想要对渲染进行这种级别的控制,则必须锁定位图位并自己完成。”

所以,我自己做。

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

为什么当 Alpha==0 时 System.Drawing.Graphics 会清空 RGB 通道? 的相关文章

  • 如何扩展 C# 内置类型,例如 String?

    我需要Trim a String 但我想删除字符串本身内所有重复的空格 而不仅仅是在其末尾或开头 我可以用这样的方法来做到这一点 public static string ConvertWhitespacesToSingleSpaces s
  • 如何在 Blazor Web 程序集中检查客户端连接状态

    我有一个 Blazor webasemmbly 应用程序 它使用 asp net core 作为后端 使用 Blazor wasm 作为前端 我有一个类可以检查 HTTP 问题 例如 notfound BadReqest 和 public
  • TortoiseGit / Winforms:合并时解析 Resource.resx

    我对 TortoiseGit 还很陌生 想知道如果 resx 文件发生冲突 如何在合并过程中解决它 例如 我可以从菜单中选择 使用他们的 尝试进行拉动和推动 但这是正确的方法吗 我可以以某种方式使用他们的并通过我的项目更改重建它吗 差异 以
  • 对 .NET Remoting CAO 的暴力攻击

    我正在尝试使用 NET 远程客户端激活对象来在多次调用期间保留客户端的身份验证信息 而不是实现需要客户端在每次调用中发送会话 ID 的会话管理系统 正如 MSDN 所说 当客户端使用 new 运算符提交对服务器对象的请求时 激活请求消息将发
  • 如何使用 MVVM light 处理 WP 8.1 上的后退按钮?

    我正在寻找适当的方法来处理 Windows Phone 8 1 WinRT 上的后退按钮按下事件NavigationService在 MVVM light 5 上可用 到目前为止 我认为最好的地方是在ViewModelLocator通过注册
  • node.js 本机插件 - 包装类的析构函数不运行

    我正在用 C 编写一个 Node js 插件 我使用 node ObjectWrap 包装一些类实例 以将本机实例与 JavaScript 对象关联起来 我的问题是 包装实例的析构函数永远不会运行 这是一个例子 point cc inclu
  • 如何知道机器的堆栈在内存中是向上还是向下增长? (JAVA)

    我有一个 C 程序来检查机器堆栈在内存中是向上还是向下增长 事情是这样的 include
  • 如何有效计算灰度图像中像素的平均“方向”?

    所以我发现我可以将图像转换为灰度图像 如下所示 public static Bitmap GrayScale this Image img var bmp new Bitmap img Width img Height using var
  • 与对象的互斥体

    我试图了解如何在 C 中将互斥体与对象一起使用 我有以下 简单的 多线程代码用作速度测试 struct Rope int n steps offset std mutex mut Rope Rope int n int steps int
  • C# 中的新类型定义

    我正在寻找定义新类型并在 C 中使用它的可能性 如下所示 类定义 public class Position public double180 Longitude get set double180 is a type within a r
  • 迁移到新 csproj 格式的 WPF 应用程序上未定义 RunCommand 属性

    我正在尝试将旧 csproj 格式构建的 WPF 应用程序迁移到为 VS2017 定义的新 csproj 格式 我已经能够编译该应用程序 但是当我尝试在 VS2017 下的调试器中启动它时 我收到以下错误消息 无法运行您的项目 未定义 Ru
  • 多次声明全局变量时,GCC 没有警告或错误[重复]

    这个问题在这里已经有答案了 假设有以下代码 File a c include
  • 在程序中使用 resources.resx 中的嵌入文件

    我有一个程序 它需要一个文本文件来保存一些信息 我有当前使用文件路径的函数 然后用它来做一些事情 但是 我想将程序构建为 exe 但文件显然不会位于同一个位置 经过研究 我发现使用嵌入式资源可以让我将文本文件添加到程序中 但我似乎无法用它做
  • 如何获得 firebird 数据库上的独占锁以执行架构更改?

    更具体地说 我正在使用 firebird 2 1 和 Visual Studio 的 DDEX Provider 并且我正在使用 c 工作 我遇到一种情况 我试图将模式更改从 C 应用到数据库 以 更新 我的数据库 在此过程中 我从 fir
  • 如何解决有关 TcpListener: 请使用 TcpListener(IPAddress localaddr, int port) 的警告?

    我创建了一个新表单 在顶部我做了 using System using System Collections Generic using System ComponentModel using System Data using Syste
  • SQL 和 Dapper 性能隐式转换

    我们如何防止 Dapper 中的 SQL 隐式转换 我们意识到 我们正在进行 SQL 隐式转换 导致索引扫描和死锁 Dapper 参数是 nvarchar 而 SQL 表列是 varchar 这导致我们所有的 sql 列都转换为 nvarc
  • LINQ to SQL 未映射的属性

    是否可以在设计器中添加自定义属性并且不将其绑定到列 我摆弄了一些设置 决定用该属性创建一个部分类 有没有办法在 ORM 设计器中显示这个字段 LINQ to SQL 设计器正在维护映射 未映射的属性需要放入单独的分部类中
  • 基于路由参数的子容器注册

    我们有一个多租户 ASP NET MVC 应用程序 为多个客户端托管预订引擎 这些客户端中的每一个都有多个可以影响 Unity 容器配置的包 我们为每个请求创建一个子容器 并根据通过路由传递的客户端和包参数注册不同的接口实现 目前 我们正在
  • ncurses 和curses - 编译器未定义的引用

    好吧 我最初一直在尝试使用一些据称仅适用于 Windows 的标头 我的错 但我已经使用curses h 重现了我需要的内容 但是我仍然收到完全相同的错误 usr bin gmake f nbproject Makefile Debug m
  • 如何等待进程及其所有子进程退出?

    是否有一个等待方法 当目标进程及其所有子进程退出时会返回 看来 Process WaitForExit 只会等待目标进程 net 中有一个错误会给出您所追求的行为 WaitForExit 如果您异步读取输出 将等待所有子进程 p Start

随机推荐