我已经在图像处理领域工作了一段时间了,我注意到了一些奇怪的事情。我正在读取BMP文件,使用简单的方法,如ReadFile等,并使用微软的BMP结构。以下是代码:
ReadFile(_bmpFile,&bmpfh,sizeof(bfh),&data,NULL);
ReadFile(_bmpFile, &bmpih, sizeof(bih), &data, NULL);
imagesize = bih.biWidth*bih.biHeight;
image = new RGBQUAD[imagesize];
ReadFile(_bmpFile,image, imagesize*sizeof(RGBQUAD),&written,NULL);这就是我读取文件的方式,然后使用简单的for-循环将其转换为灰度。
for (int i = 0; i < imagesize; i++)
{
RED = image[i].rgbRed;
GREEN = image[i].rgbGreen;
BLUE = image[i].rgbBlue;
avg = (RED + GREEN + BLUE ) / 3;
image[i].rgbRed = avg;
image[i].rgbGreen = avg;
image[i].rgbBlue = avg;
}现在,当我使用以下代码编写文件时:
#pragma pack(push, 1)
WriteFile(_bmpFile, &bmpfh, sizeof(bfh), &data, NULL);
WriteFile(_bmpFile, &bmpih, sizeof(bih), &data, NULL);
WriteFile(_bmpFile, image, imagesize*sizeof(RGBQUAD), &written, NULL);
#pragma pack(pop)文件越来越大(30 is -> 40 is)。
发生这种情况的原因是因为我使用RGBQUAD而不是RGBTRIPLE,但是如果我使用RGBTRIPLE,我在将小图片转换为灰度时遇到了问题--创建图片后无法打开它(说它的结构不对)。
文件大小也少了一个字节,(1174 is和1173 is之后)
以前有人见过这种情况(只发生在小照片上)吗?
发布于 2011-03-26 18:02:39
在BMP文件中,每个扫描线都必须被填充,所以下一个扫描线从32位边界开始。如果您每像素执行32位,这将自动发生,但是如果您使用每个像素24位,则需要添加代码来显式地执行此操作。
发布于 2011-03-26 18:27:47
您忽略了位图的步幅(曾傑瑞的注释)和像素格式。从文件大小的增加来看,这是24bpp,您正在编写它,就好像它是32bpp。你的灰度转换是错误的,人的眼睛对红,绿,蓝不一样敏感。
考虑使用GDI+,您可以在代码中包括<gdiplus.h>以使用Bitmap类。它的LockBits()方法允许您访问位图位。ColorMatrixEffect类允许您在单个操作中应用颜色转换。检查这个答案的颜色矩阵,您需要得到一个灰度图像。MSDN文档从这里开始。
发布于 2015-01-17 09:03:15
BMP中的每个水平行必须是4个字节长的倍数。 如果像素数据不占用4个字节的倍数,则在行尾添加0x00字节。对于24-bpp图像,每行字节数为(imageWidth*3 + 3) &3,填充字节数为(imageWidth*3+ 3) &3- (imageWidth*3) -(imageWidth*3)。
这一点得到了immibis的答复。
我想补充的是,数组的大小是((imageWidth*3 + 3) & ~3)*imageHeight。我希望这能帮到你
https://stackoverflow.com/questions/5444145
复制相似问题