如何将4个比特位值组合为单个整数?已实现2个的组合逻辑
问题描述
我花了好几个小时尝试解决一个问题:需要把四个二进制位平面的值组合成一个整数。目前已经实现了两个值的组合逻辑,但不知道怎么扩展到四个,相关代码如下:
int Index = ((Bitplane0_ROW[p] & (1 << N)) >> N) | (((Bitplane1_ROW[p] & (1 << N)) >> N) << 1); // 这段能正常工作
我现在卡住了,提前感谢各位的帮助。
编辑补充:完整程序代码
int main() { int Bitplane0_ROW[] = { 0b01100110 , 0b11111111, 0b01011010, 0b01111110, 0b00000000, 0b10000001, 0b11111111, 0b01111110 }; // 存储数据的数组,最后一行是第一行 int Bitplane1_ROW[] = { 0b01111110, 0b11111111, 0b11111111, 0b11011011, 0b11111111, 0b01111110, 0b00000000, 0b00000000 }; int Bitplane2_ROW[] = { 0b00000000, 0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000}; int Bitplane3_ROW[] = { 0b00000000, 0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000 }; int N = 7; // 记录当前操作的位 int c = 0; BYTE* buf = new BYTE[8 * 5]; unsigned char White[] = {255, 255, 255}; unsigned char Green[] = {53, 189,104 }; unsigned char Brown[] = {59,85,142 }; unsigned char Tan[] = {154,194,237 }; for (int p = 0; p < 8; p++) { for (int j = 0; j < 8; j++) // 处理每行的8列 { int Index = ((Bitplane0_ROW[p] & (1 << N)) >> N) | (((Bitplane1_ROW[p] & (1 << N)) >> N) << 1); // 能正常工作 if(Index == 0) { // Index 0(白色) buf[c + 0] = White[Index]; buf[c + 1] = White[Index+1]; buf[c + 2] = White[Index+2]; } else if (Index == 1) { // Index 1(绿色) buf[c + 0] = Green[Index]; buf[c + 1] = Green[Index+1]; buf[c + 2] = Green[Index+2]; } else if (Index == 2) { // Index 2(棕色) buf[c + 0] = Brown[Index]; buf[c + 1] = Brown[Index+1]; buf[c + 2] = Brown[Index+2]; } else if (Index == 3) { // Index 3(棕褐色) Index = 0; buf[c + 0] = Tan[Index]; buf[c + 1] = Tan[Index+1]; buf[c + 2] = Tan[Index+2]; } else if (Index == 15) { // Index 1(绿色) Index = 0; buf[c + 0] = Green[Index]; buf[c + 1] = Green[Index+1]; buf[c + 2] = Green[Index+2]; } c += 3; N--; } N = 7; } SaveBitmapToFile((BYTE*)buf, 8, 8, 24, 0, "C:\\Users\\Chris\\Desktop\\Link_Sprite.bmp"); delete[] buf; return 0; }
解决方案
1. 四个位平面的组合逻辑
你当前的代码已经实现了将Bitplane0作为最低位(第0位)、Bitplane1作为第1位的组合逻辑。要扩展到四个位平面,只需要遵循相同模式,把Bitplane2作为第2位、Bitplane3作为第3位加入即可:
// 分步提取每个位平面的第N位,可读性更强 int bit0 = (Bitplane0_ROW[p] & (1 << N)) >> N; int bit1 = (Bitplane1_ROW[p] & (1 << N)) >> N; int bit2 = (Bitplane2_ROW[p] & (1 << N)) >> N; int bit3 = (Bitplane3_ROW[p] & (1 << N)) >> N; int Index = bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3);
或者写成一行精简版:
int Index = ((Bitplane0_ROW[p] & (1 << N)) >> N) | (((Bitplane1_ROW[p] & (1 << N)) >> N) << 1) | (((Bitplane2_ROW[p] & (1 << N)) >> N) << 2) | (((Bitplane3_ROW[p] & (1 << N)) >> N) << 3);
这样组合出的Index范围是0~15,正好覆盖4个二进制位的所有可能值。
2. 原代码中的其他问题修正
颜色赋值错误:你当前代码里,比如
Index=1时使用Green[Index],会错误地取Green[1](绿色的G分量)作为R通道值。正确的做法是直接用颜色数组的固定索引0、1、2对应RGB通道:// 以白色为例的正确赋值 buf[c + 0] = White[0]; // R分量 buf[c + 1] = White[1]; // G分量 buf[c + 2] = White[2]; // B分量所有颜色分支都需要这样修改,
Index==3时重置Index的操作完全可以删除。缓冲区大小不足:你创建的
buf大小为8*5,但8x8的24位位图需要8*8*3=192字节,原大小会导致内存越界。应修改为:BYTE* buf = new BYTE[8 * 8 * 3];无用分支:原代码中
else if (Index == 15)永远不会触发(两位组合时Index最大为3),即使改成四位组合,也需要根据实际需求处理0~15的所有情况,而非单独判断15。
修正后的核心代码片段
for (int p = 0; p < 8; p++) { for (int j = 0; j < 8; j++) { // 组合四个位平面的第N位 int Index = ((Bitplane0_ROW[p] & (1 << N)) >> N) | (((Bitplane1_ROW[p] & (1 << N)) >> N) << 1) | (((Bitplane2_ROW[p] & (1 << N)) >> N) << 2) | (((Bitplane3_ROW[p] & (1 << N)) >> N) << 3); // 根据Index设置对应颜色 if(Index == 0) { buf[c + 0] = White[0]; buf[c + 1] = White[1]; buf[c + 2] = White[2]; } else if (Index == 1) { buf[c + 0] = Green[0]; buf[c + 1] = Green[1]; buf[c + 2] = Green[2]; } else if (Index == 2) { buf[c + 0] = Brown[0]; buf[c + 1] = Brown[1]; buf[c + 2] = Brown[2]; } else if (Index == 3) { buf[c + 0] = Tan[0]; buf[c + 1] = Tan[1]; buf[c + 2] = Tan[2]; } // 可根据需求添加Index 4~15的颜色处理逻辑 else { // 默认颜色,示例为白色 buf[c + 0] = White[0]; buf[c + 1] = White[1]; buf[c + 2] = White[2]; } c += 3; N--; } N = 7; }
内容的提问来源于stack exchange,提问作者Cyclone
相关产品推荐
相关产品推荐

