在特定的图形库中,一个表示具有32位值的像素,其由四个字节组成,用于表示四个分量RED,GREEN,BLUE和Alpha。可以使用以下定义:
typedef unsigned int Uint32;
typedef unsigned char byte;
enum Color { RED = 0, GREEN = 1, BLUE = 2, ALPHA = 3 };
一个现在需要两个免费功能:
Byte getColorComponent (Uint32 pixel, Color color);
通过位操作,检索并返回颜色参数中显示的四个颜色分量之一的值;和
void setColorComponent (Uint32 & pixel, Byte value, Color color);
它在像素中的正确位置(根据颜色参数)的字节值中停止。
答案是:
Byte getColorComponent(Uint32 pixel, Color color){ return (pixel >> (3-color)*8) & 0xFF; }
void setColorComponent(Uint32& pixel, Byte value, Color color){ pixel &= ~(0xFF << (3-color) * 8); pixel |= value << (3-color) * 8; }
我需要帮助才能理解答案。
帮助解决这类问题的好方法是使用普通的笔和纸。选择一个或多个变量的值,将其替换为表达式。继续替换子表达式,直到得到结果。
就像你简化数学表达式一样。
例如,使用getColorComponent
:
选择颜色
GREEN
(价值1
)。选择像素值
0x8a2be200
(这是一种不透明的蓝紫色,假设RGBA)。原始表达
(pixel >> (3 - color) * 8) & 0xff
替代链
(0x8a2be200 >> (3 - 1) * 8) & 0xff
(0x8a2be200 >> 2 * 8) & 0xff
(0x8a2be200 >> 16) & 0xff
0x8a2b & 0xff
0x2b
使用color == GREEN
,它可以提取32位GREEN
颜色值的RGBA颜色分量。
如果您使用任何其他颜色枚举值(RED
,BLUE
或ALPHA
)做同样的事情,您将看到它也从RGBA颜色值中提取这些组件。
我把它作为练习让读者使用这种技术来弄清楚setColorComponent
在做什么。
作为替代方案,要与计算机和调试器一起使用,请将复杂的表达式拆分为最小的子表达式,并将结果分配给临时变量。然后使用调试器逐行遍历代码,以查看结果。
有了这个,表达式(pixel >> (3 - color) * 8) & 0xff
将成为陈述
auto t1 = 3 - color; // 3 - color
auto t2 = t1 * 8; // (3 - color) * 8
auto t3 = pixel >> t2; // pixel >> (3 - color) * 8
auto t4 = t3 & 0xff; // (pixel >> (3 - color) * 8) &0xff