二进制文件位操作

时间:2013-02-14 22:16:01

标签: c++ c image-processing

我有一个图像数据的二进制文件,其中每个像素正好是4位。图像数据的布局如下:

有N个图像,其中第一个图像是1x1,第二个图像是2x2,第三个是4x4,依此类推(如果你想知道,它们是mipmap)。

给定指向数据缓冲区开头的指针,我想跳到最大的图像。

现在我知道我想要跳过多少个字节,但是这个烦人的1x1图像在开始时是4位。我不知道无论如何都要逐位递增。

如何在没有被4位关闭的情况下成功检索数据?

2 个答案:

答案 0 :(得分:4)

假设您可以更改文件格式,则可以执行以下任一操作:

  • 将填充添加到1x1图像
  • 以相反的顺序存储图像(实际上与上面相同,但不适用于mip-maps,因为你不一定知道你将拥有多少图像)

如果您无法更改格式,则可以选择以下选项:

  • 转换数据
  • 接受缓冲区偏移半个字节并相应地使用它

你说:

  

如何在不关闭所有内容的情况下成功检索数据   按4位?

这意味着你需要转换。计算以字节为单位的偏移量时,您会发现第一个包含前一个图像的半个字节。所以在紧要关头你可以像这样洗牌:

for( i = start; i < end; i++ ) {
    p[i] = (p[i] << 4) | (p[i+1] >> 4);
}

假设第一个像素是第4-7位,第二个像素是第0-3位,依此类推......如果是相反的话,只需反转这两个像素。

答案 1 :(得分:0)

// this assumes pixels points to bytes(unsigned chars)
index = ?;// your index to the pixel

byte_t b = pixels[index / 2];
if (index % 2) pixel = b >> 4;
else pixel = b & 15; 

// Or you can use
byte_t b = pixels[index >> 1];
if (index & 1) pixel = b >> 4;
else pixel = b & 15; 

无论哪种方式,只需将逻辑索引计算到文件中。除以2会将您带到像素所在字节的起点。然后只需读取正确的一半字节。

所以制作一个功能

byte_t GetMyPixel(unsigned char* pixels, unsigned index) {
  byte_t b = pixels[index >> 1];
  byte_t pixel;
  if (index & 1) pixel = b >> 4;
  else pixel = b & 15; 
  return pixel; 
} 

阅读第一张图片。

Image1x1 = GetMyPixel(pixels,0);



Image2x2_1 = GetMyPixel(pixels,1);// Top left pixel of second image
Image2x2_2 = GetMyPixel(pixels,2);// Top Right pixel of second image
Image2x2_3 = GetMyPixel(pixels,3);// Bottom left pixel of second image
... etc

所以这是一种方法。你可能需要考虑你正在使用的字节序,如果它看起来不对,那么切换像素读取的逻辑......

byte_t GetMyPixel(unsigned char* pixels, unsigned index) {
  byte_t b = pixels[index >> 1];
  byte_t pixel;
  #if OTHER_ENDIAN
  if (index & 1) pixel = b >> 4;
  else pixel = b & 15; 
  #else
  if (index & 1) pixel = b & 15;
  else pixel = b >> 4; 
  #endif
  return pixel; 
} 
相关问题