You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

UWP中SoftwareBitmap的像素获取与设置:是否有Bitmap.Get/SetPixel等效方法?

在UWP中操作SoftwareBitmap像素:替代Get/SetPixel的方案

嘿,刚好我对这个问题很熟悉!首先得明确:UWP的SoftwareBitmap类并没有像WinForms的Bitmap那样自带GetPixel/SetPixel方法,不过我们可以通过它的BitmapBuffer来实现完全等效的功能,下面一步步给你讲清楚怎么搞:

核心原理

SoftwareBitmap的像素数据都存在BitmapBuffer里,我们可以锁定这个缓冲区,把像素数据复制到字节数组中,然后根据图像的像素格式(比如最常用的BGRA8)计算每个像素的字节位置,就能读取或者修改颜色了,最后再把修改后的字节写回缓冲区就行。

具体实现代码

1. 读取指定坐标的像素颜色

public static Color GetSoftwareBitmapPixel(SoftwareBitmap bitmap, int x, int y)
{
    // 先做参数合法性检查
    if (bitmap == null || x < 0 || x >= bitmap.PixelWidth || y < 0 || y >= bitmap.PixelHeight)
        throw new ArgumentOutOfRangeException("参数超出范围啦");

    // 这里以最常用的BGRA8格式为例,其他格式需要调整逻辑
    if (bitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8)
        throw new NotSupportedException("目前只支持BGRA8格式的SoftwareBitmap哦");

    using (var buffer = bitmap.LockBuffer(BitmapBufferAccessMode.Read))
    using (var reference = buffer.CreateReference())
    {
        // 获取像素数据的字节数组
        ((IMemoryBufferByteAccess)reference).GetBuffer(out byte[] pixels, out uint capacity);

        // 计算每行的字节数(也就是 stride)
        uint stride = buffer.GetPlaneDescription(0).Stride;
        // 计算目标像素的起始字节偏移:行数*每行字节数 + 列数*每个像素的字节数(BGRA8是4字节)
        int pixelOffset = (int)(y * stride + x * 4);

        // BGRA格式的顺序是蓝、绿、红、透明通道,所以要对应读取
        byte blue = pixels[pixelOffset];
        byte green = pixels[pixelOffset + 1];
        byte red = pixels[pixelOffset + 2];
        byte alpha = pixels[pixelOffset + 3];

        return Color.FromArgb(alpha, red, green, blue);
    }
}

2. 修改指定坐标的像素颜色

public static void SetSoftwareBitmapPixel(SoftwareBitmap bitmap, int x, int y, Color color)
{
    // 参数合法性检查不能少
    if (bitmap == null || x < 0 || x >= bitmap.PixelWidth || y < 0 || y >= bitmap.PixelHeight)
        throw new ArgumentOutOfRangeException("参数超出范围啦");

    if (bitmap.BitmapPixelFormat != BitmapPixelFormat.Bgra8)
        throw new NotSupportedException("目前只支持BGRA8格式的SoftwareBitmap哦");

    using (var buffer = bitmap.LockBuffer(BitmapBufferAccessMode.ReadWrite))
    using (var reference = buffer.CreateReference())
    {
        ((IMemoryBufferByteAccess)reference).GetBuffer(out byte[] pixels, out uint capacity);

        uint stride = buffer.GetPlaneDescription(0).Stride;
        int pixelOffset = (int)(y * stride + x * 4);

        // 按照BGRA的顺序写入颜色值
        pixels[pixelOffset] = color.B;
        pixels[pixelOffset + 1] = color.G;
        pixels[pixelOffset + 2] = color.R;
        pixels[pixelOffset + 3] = color.A;
    }
}

几个重要的注意点

  • 像素格式适配:上面的代码是针对BGRA8格式写的,这是UWP里SoftwareBitmap最常用的格式。如果你的图像是其他格式(比如Rgba8、Gray8灰度图),得调整每个像素的字节数和通道顺序。比如Gray8每个像素只有1字节,直接读对应偏移的字节就行。
  • 性能优化:如果要批量处理大量像素,建议一次性操作整个字节数组,别反复调用Get/Set方法——毕竟每次锁定缓冲区和复制内存都有开销,批量处理能快很多。
  • IMemoryBufferByteAccess接口:这个接口是用来访问内存缓冲区字节的COM接口,需要你手动在代码里声明一下:
[ComImport]
[Guid("5B0D3235-4DBA-4D44-865E-8F1D0E4FD04D")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
unsafe interface IMemoryBufferByteAccess
{
    void GetBuffer(out byte* buffer, out uint capacity);
}

(要是你用的是.NET 5+或者WinUI 3,可能需要稍微调整这个接口的声明,或者用更简洁的内存访问方式)


内容的提问来源于stack exchange,提问作者Diego Alejandro Llanos Gareca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:56:49