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

如何修改BitmapImage的颜色?WinForms修改Bitmap的方法不适配怎么办

BitmapImage灰度图自定义染色实现方案

方法1:复用已有WinForms逻辑(Bitmap互转)

如果不想重写之前成熟的灰度改色逻辑,可以通过类型互转实现兼容:

  • 第一步:将BitmapImage转为System.Drawing.Bitmap
public Bitmap BitmapImageToBitmap(BitmapImage bitmapImage)
{
    using (MemoryStream outStream = new MemoryStream())
    {
        BitmapEncoder encoder = new BmpBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmapImage));
        encoder.Save(outStream);
        return new Bitmap(outStream);
    }
}
  • 第二步:调用你之前已经实现的Bitmap灰度图改色方法处理
  • 第三步:将处理完成的Bitmap转回BitmapImage
public BitmapImage BitmapToBitmapImage(Bitmap bitmap)
{
    using (MemoryStream stream = new MemoryStream())
    {
        bitmap.Save(stream, ImageFormat.Png);
        stream.Position = 0;
        BitmapImage result = new BitmapImage();
        result.BeginInit();
        result.CacheOption = BitmapCacheOption.OnLoad;
        result.StreamSource = stream;
        result.EndInit();
        result.Freeze(); // 跨线程使用必须添加此行
        return result;
    }
}

注意:.NET Core/.NET 5+项目需要先安装NuGet包System.Drawing.Common才能使用GDI+相关类型。

方法2:WPF原生像素操作(无GDI+依赖)

如果不想引入GDI+依赖,可以直接操作BitmapImage的像素数据实现灰度图染色,核心逻辑是读取每个像素的灰度值作为目标颜色的亮度权重,替换对应像素值即可:

public BitmapImage TintGrayscaleImage(BitmapImage source, System.Windows.Media.Color targetColor)
{
    int width = source.PixelWidth;
    int height = source.PixelHeight;
    int stride = width * 4; // BGRA32格式每个像素占4字节
    byte[] pixelData = new byte[height * stride];
    source.CopyPixels(pixelData, stride, 0);

    // 遍历像素完成染色
    for (int i = 0; i < pixelData.Length; i += 4)
    {
        // 灰度图R/G/B通道值相等,取任意通道作为亮度值即可
        byte luminance = pixelData[i];
        // 用亮度值作为权重计算目标颜色分量
        pixelData[i] = (byte)(targetColor.B * luminance / 255);
        pixelData[i + 1] = (byte)(targetColor.G * luminance / 255);
        pixelData[i + 2] = (byte)(targetColor.R * luminance / 255);
        // 保留原透明度逻辑,不需要透明效果可直接赋值为luminance
        pixelData[i + 3] = pixelData[i + 3] == 0 ? (byte)0 : luminance;
    }

    // 生成处理后的BitmapImage
    BitmapSource bitmapSource = BitmapSource.Create(width, height, source.DpiX, source.DpiY, 
        System.Windows.Media.PixelFormats.Bgra32, null, pixelData, stride);
    using (MemoryStream ms = new MemoryStream())
    {
        PngBitmapEncoder encoder = new PngBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
        encoder.Save(ms);
        ms.Position = 0;
        BitmapImage result = new BitmapImage();
        result.BeginInit();
        result.CacheOption = BitmapCacheOption.OnLoad;
        result.StreamSource = ms;
        result.EndInit();
        result.Freeze();
        return result;
    }
}
  • 调用示例:
    var redTintedImage = TintGrayscaleImage(originalGrayscaleImage, System.Windows.Media.Colors.Red);

该方法默认适配BGRA32格式的灰度图,若你的图像为其他像素格式,对应调整PixelFormats参数和像素读取逻辑即可。

内容的提问来源于stack exchange,提问作者Groer

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 04:54:04