显示内存中的 RGBA 图像

2023-11-27

我有一个包含 RGBA 编码图像的 C# 字节数组。在 WPF 中显示此图像的最佳方式是什么?

一种选择是从字节数组创建 BitmapSource 并将其附加到 Image 控件。但是,创建 BitmapSource 需要 RGBA32 的 PixelFormat,这在 Windows 中似乎不可用。

byte[] buffer = new byte[] { 25, 166, 0, 255, 90, 0, 120, 255 };
BitmapSource.Create(2, 1, 96d, 96d, PixelFormats.Bgra32, null, buffer, 4 * 2);

我绝对不想交换字节数组中的像素。


在深入研究 WIC 的细节之前,您可以考虑将字节交换封装在一个简单的自定义 BitmapSource 中,如下所示。它采用 RGBA 字节数组并交换覆盖的像素字节CopyPixels产生PBGRA缓冲器的方法。

您可以通过提供 RGBA 缓冲区和位图宽度来简单地创建此自定义 BitmapSource 的实例,例如

var buffer = new byte[] { 25, 166, 0, 255, 90, 0, 120, 255 };
var bitmapSource = new RgbaBitmapSource(buffer, 2);

这是实现:

public class RgbaBitmapSource : BitmapSource
{
    private byte[] rgbaBuffer;
    private int pixelWidth;
    private int pixelHeight;

    public RgbaBitmapSource(byte[] rgbaBuffer, int pixelWidth)
    {
        this.rgbaBuffer = rgbaBuffer;
        this.pixelWidth = pixelWidth;
        this.pixelHeight = rgbaBuffer.Length / (4 * pixelWidth);
    }

    public override void CopyPixels(
        Int32Rect sourceRect, Array pixels, int stride, int offset)
    {
        for (int y = sourceRect.Y; y < sourceRect.Y + sourceRect.Height; y++)
        {
            for (int x = sourceRect.X; x < sourceRect.X + sourceRect.Width; x++)
            {
                int i = stride * y + 4 * x;
                byte a = rgbaBuffer[i + 3];
                byte r = (byte)(rgbaBuffer[i] * a / 256); // pre-multiplied R
                byte g = (byte)(rgbaBuffer[i + 1] * a / 256); // pre-multiplied G
                byte b = (byte)(rgbaBuffer[i + 2] * a / 256); // pre-multiplied B

                pixels.SetValue(b, i + offset);
                pixels.SetValue(g, i + offset + 1);
                pixels.SetValue(r, i + offset + 2);
                pixels.SetValue(a, i + offset + 3);
            }
        }
    }

    protected override Freezable CreateInstanceCore()
    {
        return new RgbaBitmapSource(rgbaBuffer, pixelWidth);
    }

    public override event EventHandler<DownloadProgressEventArgs> DownloadProgress;
    public override event EventHandler DownloadCompleted;
    public override event EventHandler<ExceptionEventArgs> DownloadFailed;
    public override event EventHandler<ExceptionEventArgs> DecodeFailed;

    public override double DpiX
    {
        get { return 96; }
    }

    public override double DpiY
    {
        get { return 96; }
    }

    public override PixelFormat Format
    {
        get { return PixelFormats.Pbgra32; }
    }

    public override int PixelWidth
    {
        get { return pixelWidth; }
    }

    public override int PixelHeight
    {
        get { return pixelHeight; }
    }

    public override double Width
    {
        get { return pixelWidth; }
    }

    public override double Height
    {
        get { return pixelHeight; }
    }
}

正如评论中指出的,您可以通过实现不安全的复制操作来提高性能,该操作可能如下所示:

unsafe public override void CopyPixels(
    Int32Rect sourceRect, Array pixels, int stride, int offset)
{
    fixed (byte* source = rgbaBuffer, destination = (byte[])pixels)
    {
        byte* dstPtr = destination + offset;

        for (int y = sourceRect.Y; y < sourceRect.Y + sourceRect.Height; y++)
        {
            for (int x = sourceRect.X; x < sourceRect.X + sourceRect.Width; x++)
            {
                byte* srcPtr = source + stride * y + 4 * x;
                byte a = *(srcPtr + 3);
                *(dstPtr++) = (byte)(*(srcPtr + 2) * a / 256); // pre-multiplied B
                *(dstPtr++) = (byte)(*(srcPtr + 1) * a / 256); // pre-multiplied G
                *(dstPtr++) = (byte)(*srcPtr * a / 256); // pre-multiplied R
                *(dstPtr++) = a;
            }
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

显示内存中的 RGBA 图像 的相关文章

  • 为什么opencv videowriter这么慢?

    你好 stackoverflow 社区 我有一个棘手的问题 我需要你的帮助来了解这里发生了什么 我的程序从视频采集卡 Blackmagic 捕获帧 到目前为止 它工作得很好 同时我用 opencv cv imshow 显示捕获的图像 它也工
  • WebClient读取错误页面的内容

    我有一个加载页面内容的应用程序 我使用 WebClient 类 即使服务器返回 404 500 等错误 我也需要检索内容 我需要这样的东西 WebClient wc new WebClient string pageContent try
  • C# 中的协变和逆变

    首先我要说的是 我是一名正在学习 C 编程的 Java 开发人员 因此 我会将我所知道的与我正在学习的进行比较 我已经使用 C 泛型几个小时了 我已经能够在 C 中重现我在 Java 中知道的相同内容 除了几个使用协变和逆变的示例 我正在读
  • 关闭 XDOCUMENT 的实例

    我收到这个错误 该进程无法访问文件 C test Person xml 因为它是 被另一个进程使用 IOException 未处理 保存文件内容后如何关闭 xml 文件的实例 using System using System Collec
  • 通过引用传递时取消引用指针

    当通过引用传递给函数时取消引用指针时会发生什么 这是一个简单的例子 int returnSame int example return example int main int inum 3 int pinum inum std cout
  • 如何将字节块读入结构体

    我有一个需要处理的资源文件 它包含一组文件 首先 资源文件列出了其中包含的所有文件 以及一些其他数据 例如在此结构中 struct FileEntry byte Value1 char Filename 12 byte Value2 byt
  • 如何在 Windows 窗体中运行屏幕保护程序作为其背景?

    如何在 Windows 窗体中运行屏幕保护程序作为其背景 用户还可以在屏幕保护程序运行时与表单控件进行交互 为什么这个 我们有一个案例 需要在用户时运行 Windows Bubbles 屏幕保护程序 可以继续与表单控件交互吗 您可以使用以下
  • 使用反射获取基类的受保护属性值

    I would like to know if it is possible to access the value of the ConfigurationId property which is located in the base
  • 使用 openssl 检查服务器安全协议

    我有一个框架应用程序 它根据使用方式连接到不同的服务器 对于 https 连接 使用 openssl 我的问题是 我需要知道我连接的服务器是否使用 SSL 还是 TLS 以便我可以创建正确的 SSL 上下文 目前 如果我使用错误的上下文尝试
  • 使用scanf()时如何区分整数和字符

    我只是使用该功能scanf 代码如下 scanf d a printf d a 当我输入1时 它会像我想要的那样打印1 但即使我输入 1a 它也会像以前一样打印 1 当用户输入非整数时 例如 2 3 12ab 1 a 我想向用户显示 输入整
  • 数据损坏 C++ 和 Python 之间的管道

    我正在编写一些代码 从 Python 获取二进制数据 将其通过管道传输到 C 对数据进行一些处理 在本例中计算互信息度量 然后将结果通过管道传输回 Python 在测试时 我发现如果我发送的数据是一组尺寸小于 1500 X 1500 的 2
  • 如何在 C# 中使用 XmlDsigC14NTransform 类

    我正在尝试使用规范化 xml 节点System Security Cryptography Xml XMLDsigC14nTransformC net Framework 2 0 的类 该实例需要三种不同的输入类型 NodeList Str
  • 从包含大量文件的目录中检索文件

    我的目录包含近 14 000 000 个 wav 格式的音频样本 所有普通存储 没有子目录 我想循环浏览文件 但是当我使用DirectoryInfo GetFiles 在该文件夹上 整个应用程序冻结了几分钟 可以用另一种方式完成吗 也许读取
  • 如何在 VS Code 中为 CMake 项目设置 C/C++ IntelliSense?

    我正在尝试使用 libTooling 编写一个工具 我对其进行了设置 以便它可以使用 LLVM 文档中的示例进行编译 然而 C C IntelliSense 似乎不适用于 CMake 项目 我的工具位于
  • realloc():重新分配为 char * 上的 strcat 腾出空间时下一个大小无效 [重复]

    这个问题在这里已经有答案了 我在以下代码中收到无效内存错误 printf s n FINE 5 printf s LENGTH IS d n FINE 6 strlen buffer char realloc buffer strlen b
  • 理解 C++11 中的 std::atomic::compare_exchange_weak()

    bool compare exchange weak T expected T val compare exchange weak 是 C 11 中提供的比较交换原语之一 它是weak即使对象的值等于 它也会返回 falseexpected
  • C++ 标准中短语“构造函数没有名称”的含义

    在尝试理解 C 标准中的 构造函数没有名称 这句话时 我似乎在 clang 中发现了一个错误 有人可以证实这一点吗 VS2015 and gcc rejects this code and I think they it are is co
  • 如何强制执行特定的 UserControl 设计

    我正在编写一个基本用户控件 它将由一堆其他用户控件继承 我需要对所有这些后代控件强制执行某种设计 例如 顶部必须有几个按钮以及一个或两个标签 后代用户控件区域的其余部分可以自由放置任何内容 最初 我认为我可以将一个面板放到 Base Use
  • 元素属性语法和属性属性语法之间有语义差异吗?

    我认为元素属性语法和属性属性语法在语义上没有太大区别 但是 我发现一定有什么不同 例如 下面的例子只是演示了一个简单的触发器
  • 在 C# 中创建分部类

    我是一名学生 我不知道什么是partial class是 以下代码属于分部类 我自动创建了部分类 public partial class EGUI Form private OleDbConnection dbConn Connectio

随机推荐

  • AngularJS 中的 ng-repeat 自动对焦

    我使用 ng repeat 获取多个电话号码 div div
  • 既然我们有了 ES6 Promise,还有理由使用 Q 或 BlueBird 这样的 Promise 库吗? [关闭]

    Closed 这个问题是基于意见的 目前不接受答案 在 Node js 添加了对 Promise 的原生支持之后 还有理由使用 Q 或 BlueBird 等库吗 例如 如果您正在启动一个新项目 并且假设在该项目中您没有任何使用这些库的依赖项
  • 通过 HTTP 使用 MSMQ。如何解决队列问题?

    我目前正在尝试将 MSMQ 与 C 和 NET 结合使用以实现 IPC 我试图理解它是如何工作的 但我对它很困惑访问 MSMQ 队列时路径名称和格式名称之间的差异 我在以下帖子中发现了一些类似的问题 通过 HTTP 的 MSMQ 调用未到达
  • C++ 未初始化的局部变量

    我有一个功能 VOID GetOSVersion PDWORD major PDWORD minor PDWORD build OSVERSIONINFO osver ZeroMemory osver sizeof OSVERSIONINF
  • 读取android资源文件夹中的CSV文件

    我正在 netbeans 中开发一个 Android 应用程序 我正在尝试使用 opencsv 读取 CSV 文件 当我将文件放入资源文件夹并尝试从那里读取它时 构建时出现错误 提示资源目录无效 我应该在哪里存储 csv 文件 以便每次应用
  • 是我个人的问题,还是 WPF 是一堆数据绑定和自定义 IValueConverters?

    说真的 似乎每次我想让我的 UI 元素相互交谈时 我最终都会编写一个新的自定义 IValueConverter 有人告诉我我做错了 拜托 例子 我希望仅当我的文本框包含有效的 URI 时才启用按钮 太棒了 是时候编写代码了UriIsVali
  • 防止某些字段被 .NET Azure Web Api 中的 PATCH 覆盖

    我正在创建一个带有 NET 后端的 Azure 移动服务 该后端使用 TableController ApiController 的子类 来处理 REST 请求 在我的 PATCH 方法中 我想限制允许更新的字段集 我有一个 Account
  • jQuery 计算子元素数量

    div ul li 29 li li 16 li li 5 li li 8 li li 10 li li 7 li ul div 我想统计一下总数 li 中的元素 div div 使用 jQuery 怎么可能做到这一点 children s
  • 为什么 document.execCommand("paste") 在 Google Chrome 中不起作用?

    我的扩展有问题 我想从剪贴板粘贴数据 到目前为止 我已经得到了这个 function pasteAndGo document execCommand paste alert Pasted 出现警报 但没有粘贴任何内容 我有一种感觉docum
  • 如何使用 Spark DataFrames 查询 JSON 数据列?

    我有一个 Cassandra 表 为简单起见 它看起来像 key text jsonData text blobData blob 我可以使用 Spark 和 Spark cassandra connector 为此创建一个基本数据框架 v
  • 从响应标头中删除“服务器:Apache”

    我想知道如何完全删除 apache 在响应中发送的服务器标头 最初 它显示完整的服务器信息 例如Server Apache Ubuntu 14 04 在响应标头中 但我在某处读到将其添加到 apache2 conf 中 ServerToke
  • 如何将手机与邮箱/密码验证关联?

    我正在尝试创建一个 flutter 应用程序 在其中使用电子邮件 密码创建用户后 将其保存在 firebase 中 然后用户输入发送 OTP 的电话号码 并在验证后登录 我的问题是 当这两个步骤完成后 Firebase 将创建两个单独的帐户
  • 使用 Serde 反序列化对象时,有没有办法省略包装器/根对象?

    我有以下对象 data id 1 name South America countries data id 122 name Brazil capital Brasilia 我想定义两个结构 Continent and Country 省略
  • 为什么 GetHashCode 位于 Object 类中?

    Why 获取哈希码是对象类的一部分吗 只有一小部分类的对象用作哈希表中的键 当我们希望类的对象作为哈希表中的键时 拥有一个必须实现的单独接口不是更好吗 MS 团队决定将此方法包含在对象类中 从而使其 随处 可用 肯定是有原因的 在我看来 这
  • 如何将当前屏幕捕获为图像?

    我想添加用户在我的应用程序中捕获当前屏幕并通过电子邮件发送的功能 我有一个非常非技术性的用户群 所以我需要它尽可能简单 我打算让他们单击名为 帮助我 的菜单项 然后 它将捕获当前的应用程序屏幕 最好是 jpg 或 png 格式 然后打开 O
  • Git 接收后挂钩不起作用

    我的设置是 Windows XAMPP 服务器 启用了 cURL 并安装了 Git 和 Hudson Hudson 每分钟轮询一次 Git 以查找更改 如果找到更改 就会创建一个构建 我使用这个版本作为我的测试服务器 这很好用 我想在我的中
  • Chart.js 压缩条形图上的垂直轴

    我有一个数据集 其中最后一个值总是非常高 这会导致我的条形图出现问题 几乎所有其他值如果不悬停在它们上面就很难有感觉 这是一个屏幕截图 这就是我想要达到的目标 所以我的问题是 这可以在普通 Chart js 中实现吗 或者我需要一个插件吗
  • 在 JavaScript (node.js) 中设置错误原因

    是否可以指定 JavaScript node js 中错误的原因 我找到了Mozilla 文档它定义了如何设置消息 文件 行 但不定义错误原因 我对此感兴趣的原因是我想捕获内部错误并将其传播到嵌套异常中的表面 类似于 Java 中的异常链
  • 如何从类似文件的对象中使用 python mimetypes.guess_type

    gt gt gt mimetypes guess type picture jpg image jpeg None 现在我有一个类似文件的对象 例如 stingIO 哪些内容是图像的数据 我如何从类似文件的对象中检测 mimetypes p
  • 显示内存中的 RGBA 图像

    我有一个包含 RGBA 编码图像的 C 字节数组 在 WPF 中显示此图像的最佳方式是什么 一种选择是从字节数组创建 BitmapSource 并将其附加到 Image 控件 但是 创建 BitmapSource 需要 RGBA32 的 P