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

图像转黑白的ToBlackAndWhite方法失效,输出全黑/全白图像求助

问题分析:ToBlackAndWhite方法输出全黑/全白图像的原因

核心问题:错误实例化System.Drawing.Color结构体

System.Drawing.Color是特殊结构体,没有公开的实例构造函数,不能直接通过new Color(r, g, b)创建有效实例。你代码中用new(pixel[2], pixel[1], pixel[0])创建的Color对象内部ARGB值不符合预期,导致GetBrightness()、GetHue()、GetSaturation()等方法返回结果全部偏向一侧(要么全满足阈值条件,要么全不满足),最终所有像素被统一设为黑色或白色。

其他潜在问题:忽略Alpha通道(针对带透明的像素格式)

你的InvertTransparency方法处理了pixel[3](Alpha通道),说明位图大概率是32位ARGB格式,但ToBlackAndWhite方法存在两个疏漏:

  • 创建Color时未传入Alpha值,导致颜色计算未考虑透明度,影响亮度/色相/饱和度的判断准确性;
  • 修改像素时未设置Alpha通道,可能导致最终图像出现透明区域(视觉上显示为黑色)。

修复步骤

1. 正确创建Color实例

使用Color.FromArgb()静态方法替代直接实例化:

  • 若位图为带Alpha通道格式(如Format32bppArgb):
    var color = Color.FromArgb(pixel[3], pixel[2], pixel[1], pixel[0]);
    
  • 若为无Alpha通道格式(如Format24bppRgb):
    var color = Color.FromArgb(255, pixel[2], pixel[1], pixel[0]);
    

2. 同步处理Alpha通道(若适用)

如果位图包含Alpha通道,修改像素时需同步设置Alpha值为不透明,避免出现透明区域:

if (IsWhite(color))
{
    pixel[2] = MAX; // R
    pixel[1] = MAX; // G
    pixel[0] = MAX; // B
    if (pixelSize == 4) // 32位ARGB格式
        pixel[3] = MAX; // Alpha设为不透明
    sum--;
}
else
{
    pixel[2] = MIN;
    pixel[1] = MIN;
    pixel[0] = MIN;
    if (pixelSize == 4)
        pixel[3] = MAX;
    sum++;
}

3. 验证MAX和MIN常量值

确保MAX为255、MIN为0,这是8位颜色分量的正确极值。

修复后的ToBlackAndWhite方法示例

public float ToBlackAndWhite(BlackWhiteMode mode)
{
    var data = _bmp.LockBits(new Rectangle(0, 0, Width, Height), ImageLockMode.ReadWrite, _bmp.PixelFormat);

    var IsWhite = mode switch
    {
        BlackWhiteMode.Brightness => new Predicate<Color>(x => x.GetBrightness() > 0.5),
        BlackWhiteMode.Hue => new Predicate<Color>(x => x.GetHue() > 180),
        _ => new Predicate<Color>(x => x.GetSaturation() > 0.5)
    };
    
    int sum = 0;
    unsafe
    {
        var pixelSize = Image.GetPixelFormatSize(_bmp.PixelFormat) / 8;
        var isArgb = pixelSize == 4; // 判断是否为32位带Alpha格式

        var ptr = (byte*)data.Scan0;

        byte* row;
        byte* pixel;
        for (int y = 0; y < data.Height; y++)
        {
            row = ptr + y * data.Stride;

            for (int x = 0; x < data.Width; x++)
            {
                pixel = row + x * pixelSize;
                Color color;

                // 正确创建Color实例
                if (isArgb)
                    color = Color.FromArgb(pixel[3], pixel[2], pixel[1], pixel[0]);
                else
                    color = Color.FromArgb(255, pixel[2], pixel[1], pixel[0]);

                if (IsWhite(color))
                {
                    pixel[2] = 255; // MAX
                    pixel[1] = 255;
                    pixel[0] = 255;
                    if (isArgb)
                        pixel[3] = 255;
                    sum--;
                }
                else
                {
                    pixel[2] = 0; // MIN
                    pixel[1] = 0;
                    pixel[0] = 0;
                    if (isArgb)
                        pixel[3] = 255;
                    sum++;
                }
            }
        }
    }

    _bmp.UnlockBits(data);

    return (float)Math.Abs(sum) / PixelCount;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.18 00:15:10