C++实现保存24位BMP图像
我想要保存的是24位真彩图,对于24位真彩图,可以不需要颜色表,也就是说54个字节后面紧跟的就是图像数据,所以我没有写入文件(不知道这是不是我保存后的图像打不开的原因)
BITMAPFILEHEADER,BITMAPINFOHEADER文件的书写如下:
int size;
size=3*imageWidth;
if (3*imageWidth%4)
size+=4-3*imageWidth%4;
size*=imageHeight;
BITMAPFILEHEADER bfh;
BITMAPINFOHEADER bih;
bih.biBitCount=24;
bih.biClrImportant=0;
bih.biClrUsed=0;
bih.biCompression=BI_RGB;
bih.biHeight=imageHeight;
bih.biPlanes=1;
bih.biSize=sizeof(BITMAPINFOHEADER);
bih.biSizeImage=size;
bih.biWidth=imageWidth;
bih.biXPelsPerMeter=0;
bih.biYPelsPerMeter=0;
bfh.bfReserved1=bfh.bfReserved2=0;
bfh.bfSize=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+size;
bfh.bfType=((WORD)('M'<<8)|'B');
bfh.bfOffBits=54;
stream=fopen("b.bmp","wb");
if(stream==NULL) return;
fwrite(&bfh,sizeof(bfh),sizeof(bfh),stream);
fwrite(&bfh,sizeof(bfh),sizeof(bih),stream);
for(i=0;i<ImageHeight;i++)
for(j=0;j<ImageWidth;j++)
{
{
fwrite(&buffertemp[i][j*3],1,sizeof(BYTE),stream);
fwrite(&buffertemp[i][j*3+1],1,sizeof(BYTE),stream);
fwrite(&buffertemp[i][j*3+2],1,sizeof(BYTE),stream);
}
}
fclose(stream);
请问大家问题出在哪里,如何修改,可以不要颜色表的吧?
[解决办法]
写完整像素内容不需要调色板,
你的代码太乱了,不想看,不过,我写了个相当清晰的,并且可用的代码:
bool BMP_SaveFile(const char* szFile, const void* pBmp, int width, int height, int bitCount=32){ FILE* pFile = fopen(szFile, "wb"); assert(pFile != NULL); int bmp_size = width*height*(bitCount/8); // 【写位图文件头】 BITMAPFILEHEADER bmpHeader; bmpHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmp_size; // BMP图像文件的大小 bmpHeader.bfType = 0x4D42; // 位图类别,根据不同的操作系统而不同,在Windows中,此字段的值总为‘BM’ bmpHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER); // BMP图像数据的偏移位置 bmpHeader.bfReserved1 = 0; // 总为0 bmpHeader.bfReserved2 = 0; // 总为0 fwrite(&bmpHeader, sizeof(bmpHeader), 1, pFile); BITMAPINFOHEADER bmiHeader; bmiHeader.biSize = sizeof(bmiHeader); // 本结构所占用字节数,即sizeof(BITMAPINFOHEADER); bmiHeader.biWidth = width; // 位图宽度(单位:像素) bmiHeader.biHeight = height; // 位图高度(单位:像素) bmiHeader.biPlanes = 1; // 目标设备的级别,必须为1 bmiHeader.biBitCount = bitCount; // 像素的位数(每个像素所需的位数,范围:1、4、8、24、32) bmiHeader.biCompression = 0; // 压缩类型(0:不压缩 1:BI_RLE8压缩类型 2:BI_RLE4压缩类型) bmiHeader.biSizeImage = bmp_size; // 位图大小(单位:字节) bmiHeader.biXPelsPerMeter = 0; // 水平分辨率(像素/米) bmiHeader.biYPelsPerMeter = 0; // 垂直分辨率(像素/米) bmiHeader.biClrUsed = 0; // 位图实际使用的彩色表中的颜色索引数 bmiHeader.biClrImportant = 0; // 对图象显示有重要影响的颜色索引的数目 // 【写位图信息头(BITMAPINFO的bmiHeader成员)】 fwrite(&bmiHeader, sizeof(bmiHeader), 1, pFile); // 【写像素内容】 fwrite(pBmp, bmp_size, 1, pFile); fclose(pFile); return true;}
[解决办法]
FILE *f;unsigned char *img = NULL;int filesize = 54 + 3*w*h; //w is your image width, h is image height, both intif( img ) free( img );img = (unsigned char *)malloc(3*w*h);memset(img,0,sizeof(img));for(int i=0; i<w; i++){ for(int j=0; j<h; j++){ x=i; y=(yres-1)-j; r = red[i][j]*255; g = green[i][j]*255; b = blue[i][j]*255; if (r > 255) r=255; if (g > 255) g=255; if (b > 255) b=255; img[(x+y*w)*3+2] = (unsigned char)(r); img[(x+y*w)*3+1] = (unsigned char)(g); img[(x+y*w)*3+0] = (unsigned char)(b);}}unsigned char bmpfileheader[14] = {'B','M', 0,0,0,0, 0,0, 0,0, 54,0,0,0};unsigned char bmpinfoheader[40] = {40,0,0,0, 0,0,0,0, 0,0,0,0, 1,0, 24,0};unsigned char bmppad[3] = {0,0,0};bmpfileheader[ 2] = (unsigned char)(filesize );bmpfileheader[ 3] = (unsigned char)(filesize>> 8);bmpfileheader[ 4] = (unsigned char)(filesize>>16);bmpfileheader[ 5] = (unsigned char)(filesize>>24);bmpinfoheader[ 4] = (unsigned char)( w );bmpinfoheader[ 5] = (unsigned char)( w>> 8);bmpinfoheader[ 6] = (unsigned char)( w>>16);bmpinfoheader[ 7] = (unsigned char)( w>>24);bmpinfoheader[ 8] = (unsigned char)( h );bmpinfoheader[ 9] = (unsigned char)( h>> 8);bmpinfoheader[10] = (unsigned char)( h>>16);bmpinfoheader[11] = (unsigned char)( h>>24);f = fopen("img.bmp","wb");fwrite(bmpfileheader,1,14,f);fwrite(bmpinfoheader,1,40,f);for(i=0; i<h; i++){ fwrite(img+(w*(h-i-1)*3),3,w,f); fwrite(bmppad,1,(4-(w*3)%4)%4,f);}fclose(f);
[解决办法]
楼主生成文件时写了两次 bfh, 没有写 bih, 所以图片文件是错误的。