1

我有一个任务,要求我读取图片文件作为每个像素的 uint32_t 变量(3 个字节用于颜色,1 个字节用于饱和度)。然后我应该以各种方式过滤图片,例如红色过滤器,您将所有蓝色和绿色字节设置为 0。我正在努力弄清楚如何更改 uint32_t 变量中的 4 个单独的字节。

4

3 回答 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 回答