C++:.bmp 到文件中的字节数组
Posted
技术标签:
【中文标题】C++:.bmp 到文件中的字节数组【英文标题】:C++: .bmp to byte array in a file 【发布时间】:2012-04-12 13:25:05 【问题描述】:是的,我已经解决了与此相关的其他问题,但我发现它们没有多大帮助。他们有一些帮助,但我仍然有点困惑。所以这里我需要做什么:
我们有一个 132x65 的屏幕。我有一个 132x65 的 .bmp。我想通过 .bmp 并将其分成小的 1x8 列,以获取该 32 位列的二进制文件。然后做 132 次,然后做 9 次。任何不是白色的东西都应该算作一点点。示例:
如果图片左上角的像素是任何非白色的颜色,而下方的 7 个像素是白色,那么这将是数组的第一个元素,即该数字的十六进制,所以数组看起来像这样: array [] = 0x01 然后它将继续填充这 132 列,然后对 9 个“部分”行再次执行此操作。并且文件结果将只是单独文件中的那个数组。
我了解此标题格式,我已阅读有关 .bmp 文件格式的 wiki 文章,我的主要问题是我真的不知道如何与 .bmp 进行交互,而我实际上希望它进入并交互与图像中的每个像素。我真的不需要整个东西,但也许只是从 .bmp 中获取每个像素并将像素的颜色输出到文件或其他东西的示例。我的 c++ 有点生疏(最近一直在做 java 和 javscript)。
【问题讨论】:
你选择了 BMP 库了吗? 不,我愿意使用其中的任何一个。我已经浏览了其中的一些,但不确定哪个是最好的/最简单的/最快的。 我主要尝试使用 CImage 类。我的问题是我真的不知道如何与 .bmp 文件进行交互。我真的只需要一个例子来处理某人可能就像进入一个 .bmp 文件并设置像素颜色或其他东西一样简单。就像我说的那样,我已经有一段时间没有做任何 c++ 了,所以当我尝试与 .bmp 文件交互时,我觉得自己只是在困惑自己。 【参考方案1】:如果您想读取已知格式的 BMP 并且不关心它是如何完成的(即,仅限内部的事情),您可以只使用 BMP,忽略标题并将其用作像素数组。它从左下角开始逐行存储。它的打包方式有一些细节问题,但根据我的经验,如果您拍摄 32bpp 图像,则可以完全忽略它。
作为一个非常简单的例子:
unsigned int *buffer;
void readfile()
FILE *f = fopen("file.bmp", "rb");
buffer = new unsigned int[132*65];
fseek(f, 54);
fread(buffer, 132*65*4, 1, f);
fclose(f);
unsigned int getpixel(int x, int y)
//assuming your x/y starts from top left, like I usually do
return buffer[(64 - y) * 132 + x];
【讨论】:
这就是我想要的!但他们的问题是我不知道如何在语法上做到这一点......就像我如何与第一个像素进行交互? 添加了代码示例。 54 是我通常在 bmp 文件中看到的,但根据可选标题的不同,您的可能会有所不同。为清楚起见,请使用十六进制编辑器打开它并亲自查看。 你说“从左下角开始”。然后在示例中“从左上角开始”。可能需要澄清一下.. 好的,所以我明白了,我正在阅读越界。傻我。但这是我的问题,为什么它总是返回零?我从 getpixel 得到的价值是多少?无论如何,如果 getpixel 的值为白色,则返回 0,如果是其他颜色,则返回 1? 从中得到的值是给定像素的RGB值。请注意,我的示例假定具有正确纵横比的 32 位彩色 BMP 和预期的标题。【参考方案2】:我遇到了同样的问题,但是通过阅读 BMP 文件格式描述,我编写了一个函数,该函数读取 .BMP 文件并将其存储到数组中。 也许这个功能可以帮助你:
unsigned int PIC::BinToNum(char *b,int bytes)
unsigned int tmpx = 0;
unsigned int pw = 1;
for(int i=0;i<bytes;i++)
tmpx += ((unsigned char)b[i]* pw);
pw = pw * 256;
return tmpx;
int PIC::Open(const char *path)
int pad = 0;
unsigned int sof = 0;
unsigned int tx = 0;
char tmp[4] = 0,0,0,0;
fstream file;
file.open(path,ios::in);
if(file.fail())
width=height=ColorBits=size=0;
return -1;
else
file.seekg(0,ios::beg);
file.read(tmp,2);
if(!(tmp[0] == 66 && tmp[1] == 77))
width=height=ColorBits=size=0;
return 0;
else
file.seekg(2,ios::beg); // 0x2 size
file.read(tmp,4);
size = BinToNum(tmp,4);
file.seekg(18,ios::beg); // 0x12 width
file.read(tmp,4);
width = BinToNum(tmp,4);
file.seekg(22,ios::beg); // 0x16 height
file.read(tmp,4);
height = BinToNum(tmp,4);
file.seekg(28,ios::beg); // 0x1C Bits per Pixel
file.read(tmp,2);
ColorBits = BinToNum(tmp,2);
file.seekg(10,ios::beg); // 0x0A start offset
file.read(tmp,4);
sof=BinToNum(tmp,4);
file.seekg(34,ios::beg); // 0x22 Padding
file.read(tmp,4);
pad = BinToNum(tmp,4);
pad = (int)(pad / height); // Compute Spacing in each row
pad = pad - (width*ColorBits/8);
// Initialize Matrix//
matrix = new(unsigned int[height*width]);
for(int h=height-1;h>=0;h--)
for(int w=0;w<=width-1;w++)
file.seekg(sof,ios::beg);
file.read(tmp,(int)(ColorBits/8));
tx = BinToNum(tmp,(int)(ColorBits/8));
matrix[(h*width)+w] = tx;
sof+=(int)(ColorBits/8);
sof +=pad;
file.close();
return 1;
Note:This functions is member of a class that i named it "PIC"...
【讨论】:
以上是关于C++:.bmp 到文件中的字节数组的主要内容,如果未能解决你的问题,请参考以下文章