我有一个任务,要求我读取图片文件作为每个像素的 uint32_t 变量(3 个字节用于颜色,1 个字节用于饱和度)。然后我应该以各种方式过滤图片,例如红色过滤器,您将所有蓝色和绿色字节设置为 0。我正在努力弄清楚如何更改 uint32_t 变量中的 4 个单独的字节。
问问题
1195 次
3 回答
1
使用位移:
uint32_t pixel = 0;
uint8_t byte0 = 1, byte1 = 2, byte2 = 3, byte3 = 4;
pixel = (pixel & 0xFFFFFF00) | byte0;
pixel = (pixel & 0xFFFF00FF) | ((uint32_t)byte1 << 8);
pixel = (pixel & 0xFF00FFFF) | ((uint32_t)byte2 << 16);
pixel = (pixel & 0x00FFFFFF) | ((uint32_t)byte3 << 24);
printf("0x%x\n", pixel); /* --> 0x4030201 */
与工会:
typedef union pixel_s {
uint32_t uint32_value;
uint8_t uint8_value[4];
} pixel_t;
pixel_t pixel;
uint8_t byte0 = 1, byte1 = 2, byte2 = 3, byte3 = 4;
pixel.uint8_value[0] = byte0;
pixel.uint8_value[1] = byte1;
pixel.uint8_value[2] = byte2;
pixel.uint8_value[3] = byte3;
printf("0x%x\n", pixel.uint32_value); /* --> 0x4030201 */
正如其他人提到的,这取决于机器。但很可能您使用的是 x86 或 x86_64,因此它将是小端。上面的代码是针对小端的。
于 2019-11-21T19:50:21.663 回答
0
您还可以使用预处理宏来修改变量中的某个字节。也许它为您提供了更灵活的解决方案。
#define SET_BYTE(INPUT, VALUE, POSITION) (INPUT=(VALUE<<(POSITION<<3))|(INPUT&(0xFFFFFFFF^(0xFF<<(POSITION<<3)))))
其中INPUT
是您要修改的数据,VALUE
是新值,是值POSITION
的字节位置。
用法:
unsigned long data = 0xFFFFFFFF;
SET_BYTE(data , 0xAA, 2); /* set 0xAA to byte position 2; data = 0xFFAAFFFFFF */
很可能我的定义看起来有点混乱,但会发生以下情况:(INPUT&(0xFFFFFFFF^(0xFF<<(POSITION<<3))))
宏的一部分在正确的字节位置创建一个 0x00 位掩码并清除字节。然后在(VALUE<<(POSITION<<3))
正确的位置设置新值。最后,我们在逻辑上还是使用新值的位掩码。
于 2019-11-21T20:45:02.583 回答
0
这个流行的答案描述了如何修改单个位。从那里,您可以将其扩展为对一个字节(8 位)进行操作。由于这是作业,我不想完全回答你,但如果你仍然无法得到它,请评论。
于 2019-11-21T18:47:24.080 回答