Color.FromArgb 方法作为一个Int32
参数。Color.White的值是#FFFFFFFF
ARGB,它是4.294.967.295
十进制的(远大于int.MaxValue
)。我在这里不明白什么?如果有效的 ARGB 值高于 a 的最大值,该方法如何int
作为参数int
?
8 回答
不幸的是,由于Color.FromArgb采用 anint
而不是 a uint
,因此您需要对大于 int.MaxValue 的颜色使用unchecked关键字。
var white = Color.FromArgb(unchecked((int)0xFFFFFFFF));
你的困惑在于标牌。尽管Int32.MaxValue等于 2,147,483,647,但它是有符号的。
如果您查看UInt32.MaxValue,它是无符号的,如您所见,最大值为 4,294,967,295。
您会看到,二进制有符号数字使用最左边的位来确定它是正数还是负数。二进制中的无符号数字没有带符号位并利用最后一位,从而使您的存储容量基本上翻了一番。
我认为Color
类使用Int32
而不是 unsigned 的部分原因是因为 unsigned int 不符合 CLS,如本 SO Question中所述
32 位 ARGB 值的字节顺序为 AARRGGBB。由 AA 表示的最高有效字节 (MSB) 是 alpha 分量值。第二、三、四字节分别用RR、GG、BB表示,分别是颜色分量红、绿、蓝。
http://msdn.microsoft.com/en-us/library/2zys7833(v=vs.110).aspx
该方法似乎将 int32 分解为 32 位并将其转换为 AARRGGBB,即每个参数 A、R、G 和 B 的两个半字节(1 个字节)。
这是有效的,因为 FFFFFFFF 十六进制中的每个数字都转换为单个半字节。每个空间具体等于 4 位。因此,这个位表示直接转换为 32 位,可以表示为单个 int32。
提供更多细节:
十六进制空格的最大值是 F(或十进制的 15)。
4 位(1 个半字节)的最大值是 (8, 4, 2, 1),也是 15。
因此,FFFFFFFF = 1111 1111 1111 1111 1111 1111 1111 1111 然后表示为 int32 。
正如@icemanind 指出的那样,第一位是为符号(+ 或 -)保留的,因此将 int32 的数值限制为 2,147,483,647。
对这种方法重要的不是数值,而是位值。
实际的问题是你想输入一个八位的十六进制数,但是因为单参数版本使用的是int
a 而不是 a uint
,所以很难表示 Alpha 值高于 &7F 的颜色。这是因为 anint
使用一位来表示符号。
最简单的解决方案是使用四参数版本:
var whiteColor = Color.FromArgb(0xFF, 0xFF, 0xFF, 0xFF);
AColor
由四个重要字段组成,A
(alpha)、R
(red)、G
(green) 和B
(blue)。每个都是八位。四个八位值适合 int32。虽然 MSB 可能是符号位,但它被忽略了。
0xFFFFFFFF
表示为 时可能是负数int
,但它是白色的颜色。
根据Color.FromArgb Method (Int32)的 MSDN 页面,您没有传入int
颜色的实际值。例如,要变红,你会调用Color.FromArgb(0x78FF0000)
. 所以,对于白色,你应该只需要调用Color.FromArgb(0xFFFFFFFF)
.
没关系。
#FFFFFFFF 是二进制的 11111111111111111111111111111111。
如果您使用的是 unsigned ints,则十进制为 4.294.967.295 。如果您使用有符号整数,则将其解释为 -1。
但是实际的十进制值并不重要;重要的是各个位的值。
带符号的 int 仍然可以存储 4.294.967.295 个值,其中只有一半是负数。位是一样的。
您可以编写 0x00FFFFFF-0x01000000 编译器将正常工作