2008-11-26 49 views
1

我有一个NSColor,我真的很想要它表示的32位RGBA值。有没有简单的方法来获得这个,除了提取浮点数组件,然后乘法和ORing,并通常做严重的,依赖endian的东西?从NSColor中提取32位RGBA值

编辑:感谢您的帮助。真的,我期望的是一个可可功能,已经做到了这一点,但我自己也很酷。

回答

5

另一个更蛮力的方法是创建一个临时的CGBitmapContext并填充颜色。

NSColor *someColor = {whatever}; 
uint8_t data[4]; 

CGContextRef ctx = CGBitmapContextCreate((void*)data, 1, 1, 8, 4, colorSpace, kCGImageAlphaFirst | kCGBitmapByteOrder32Big); 

CGContextSetRGBFillColor(ctx, [someColor redComponent], [someColor greenComponent], [someColor blueComponent], [someColor alphaComponent]); 

CGContextFillRect(ctx, CGRectMake(0,0,1,1)); 

CGContextRelease(ctx); 

FWIW,每个分量颜色值没有8位的端点问题。字节序只有16位或更多的整数。你可以以任何你想要的方式布置内存,但是无论是大端还是小端机器,8位整数值都是相同的。 (ARGB是Core Graphics和Core Image I相信的默认8位格式)。

为什么不这样?:

uint32_t r = (uint32_t)(MIN(1.0f, MAX(0.0f, [someColor redComponent])) * 255.0f); 
uint32_t g = (uint32_t)(MIN(1.0f, MAX(0.0f, [someColor greenComponent])) * 255.0f); 
uint32_t b = (uint32_t)(MIN(1.0f, MAX(0.0f, [someColor blueComponent])) * 255.0f); 
uint32_t a = (uint32_t)(MIN(1.0f, MAX(0.0f, [someColor alphaComponent])) * 255.0f); 
uint32_t value = (r << 24) | (g << 16) | (b << 8) | a; 

然后你确切地知道它是如何在内存布局。

还是这个,如果更清楚你:

uint8_t r = (uint8_t)(MIN(1.0f, MAX(0.0f, [someColor redComponent])) * 255.0f); 
uint8_t g = (uint8_t)(MIN(1.0f, MAX(0.0f, [someColor greenComponent])) * 255.0f); 
uint8_t b = (uint8_t)(MIN(1.0f, MAX(0.0f, [someColor blueComponent])) * 255.0f); 
uint8_t a = (uint8_t)(MIN(1.0f, MAX(0.0f, [someColor alphaComponent])) * 255.0f); 

uint8_t data[4]; 
data[0] = r; 
data[1] = g; 
data[2] = b; 
data[3] = a; 
+1

“FWIW,有与每分量8位颜色值没有尾数的问题。”是有,如果你处理的像素为32位单元(具有诸如uint32_t的类型)。试一试:在一个系统上保存一个RGBA像素,然后将其加载到另一个具有不同字节顺序的像素上。你会得到ABGR。 – 2008-11-26 23:22:12

1

将4个浮点数转换为它们的整数表示形式,但是要实现这一点,是唯一的方法。

3

并非所有的颜色都有的RGBA表示。它们可能在RGBA中有一个近似值,但这可能会也可能不准确。此外,Core Graphics将“颜色”绘制为图案(例如,某些Mac OS X版本的窗口背景颜色)。