C++实现保存24位BMP图像

richiessh 2012-09-16 09:19:35
我想要保存的是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);
请问大家问题出在哪里,如何修改,可以不要颜色表的吧?
...全文
576 4 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
ryfdizuo 2012-09-18
  • 打赏
  • 举报
回复

FILE *f;
unsigned char *img = NULL;
int filesize = 54 + 3*w*h; //w is your image width, h is image height, both int
if( 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);
vnking 2012-09-18
  • 打赏
  • 举报
回复
楼主生成文件时写了两次 bfh, 没有写 bih, 所以图片文件是错误的。
weiwuyuan 2012-09-17
  • 打赏
  • 举报
回复
写完整像素内容不需要调色板,
你的代码太乱了,不想看,不过,我写了个相当清晰的,并且可用的代码:

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;
}


你自己比对下吧

19,472

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 图形处理/算法
社区管理员
  • 图形处理/算法社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧