如何检查两个System.Drawing.Color结构是否在16位色深度下表示相同的颜色?

7
如何检查两个System.Drawing.Color结构是否代表16位颜色深度(或基于Screen.PrimaryScreen.BitsPerPixel值)中的相同颜色?例如,我将Form.TransparencyKey设置为Value1(Color类型),我想要检查当用户选择窗体的新背景颜色(Value2)时,我不会将整个窗体设置为透明。在32位颜色深度屏幕上,我只需比较这两个值:if (Value1 == Value2)。然而,在16位颜色深度屏幕上,这种方法不起作用,因为更多的Color值对于Value2将表示与Value1相同的实际16位颜色,这是我通过艰苦的努力发现的。
3个回答

1
尝试以下代码:
void MyTestMethod() {
    TransparencyKey = Color.FromArgb(128, 128, 64);
    BackColor = Color.FromArgb(128, 128, 71);

    byte tR = ConvertR(TransparencyKey.R);
    byte tG = ConvertG(TransparencyKey.G);
    byte tB = ConvertB(TransparencyKey.B);

    byte bR = ConvertR(BackColor.R);
    byte bG = ConvertG(BackColor.G);
    byte bB = ConvertB(BackColor.B);

    if (tR == bR &&
        tG == bG &&
        tB == bB) {
        MessageBox.Show("Equal: " + tR + "," + tG + "," + tB + "\r\n" +
            bR + "," + bG + "," + bB);
    }
    else {
        MessageBox.Show("NOT Equal: " + tR + "," + tG + "," + tB + "\r\n" +
            bR + "," + bG + "," + bB);
    }
}

byte ConvertR(byte colorByte) {
    return (byte)(((double)colorByte / 256.0) * 32.0);
}

byte ConvertG(byte colorByte) {
    return (byte)(((double)colorByte / 256.0) * 64.0);
}

byte ConvertB(byte colorByte) {
    return (byte)(((double)colorByte / 256.0) * 32.0);
}

只需调整TransparancyKey和BackColor,看看它是否适用于您。对我来说是有效的。是的,我知道它是臃肿且丑陋的代码,但它只是作为示例。


只是为了理解,如果您能给我更多关于为什么要将红色值乘以32、绿色值乘以64和蓝色值乘以32的细节,谢谢。 - TechAurelian
由于nobugz的回答所述原因:Windows中的16位RGB(真实)颜色是由5、6和5位(2的5次方为32,2的6次方为64)构建的。因此,如果您将原始的红色和蓝色字节除以256并将它们乘以32,则会得到向下舍入的5位表示。绿色的6位也适用相同的方法。 - Webleeuw

1

16位颜色有两种像素格式,555和565。在比较它们之前,您必须使用0xf8(5位)和0xfc(6位)掩码来屏蔽R、G和B值。请记住,在运行设计师的计算机上运行的程序并不代表您的程序实际运行的计算机。


0

由于ColorTranslator.ToWin32在幕后使用,这个能行吗?

if( ColorTranslator.ToWin32(Value1) == ColorTranslator.ToWin32(Value2) )

这样做不行,因为它总是会得到一个32位颜色的整数表示。 - Webleeuw
以下是ColorTranslator.ToWin32的.NET源代码:<code> "public static int ToWin32(Color c) { return c.R << Win32RedShift | c.G << Win32GreenShift | c.B << Win32BlueShift; }" </code> 其中Win32RedShift = 0; Win32GreenShift = 8; Win32BlueShift = 16;这个代码能否被修改以将值转换为16位颜色深度?或者更一般地说,转换为Screen.PrimaryScreen.BitsPerPixel颜色深度? - TechAurelian

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接