我写了一个将24位bmp图像转换成8位bmp的小程序,不过转换结果不对,想了很久一直没想明白,特向各位大牛请教
bool ImageReader::depthfrom24to8(char *newimageName)
{
//以二进制写的方式打开文件
FILE *fp=fopen(newimageName,"wb");
if(fp==0) return 0;
//灰度图像8位深度
int newbiBitCount=8;
//待存储图像数据每行字节数为4的倍数
int lineByte=(imagewidth * newbiBitCount/8+3)/4*4;
//为新图像申请空间
unsigned char *ptempimageBuf=new unsigned char[lineByte*imageheight];
if(!ptempimageBuf)
return 0;
for(int i=0;i<imageheight;i++) //color change from 24 to 8 bit
{
for(int j=0,k=0;j<imagewidth;j++)
{
int B=*(pimageBuf+i*lineByte+3*j+0);
int G=*(pimageBuf+i*lineByte+3*j+1);
int R=*(pimageBuf+i*lineByte+3*j+2);
ptempimageBuf[i*lineByte+j]=(BYTE)(R*0.299 + G*0.587 + B*0.114);
}
}
//颜色表大小,以字节为单位,灰度图像颜色表为1024字节,彩色图像颜色表大小为0
int colorTablesize=1024;
//申请位图文件头结构变量,填写文件头信息
BITMAPFILEHEADER fileHead;
fileHead.bfType = 0x4D42;//bmp类型
//bfSize是图像文件4个组成部分之和
fileHead.bfSize= sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER)
+ colorTablesize + lineByte*imageheight;
fileHead.bfReserved1 = 0;
fileHead.bfReserved2 = 0;
//bfOffBits是图像文件前3个部分所需空间之和
fileHead.bfOffBits=54+colorTablesize;
//写文件头进文件
fwrite(&fileHead, sizeof(BITMAPFILEHEADER),1, fp);
//申请位图信息头结构变量,填写信息头信息
BITMAPINFOHEADER head;
head.biBitCount=newbiBitCount;
head.biClrImportant=0;
head.biClrUsed=0;
head.biCompression=0;
head.biHeight=imageheight;
head.biPlanes=1;
head.biSize=40;
head.biSizeImage=lineByte*imageheight;
head.biWidth=imagewidth;
head.biXPelsPerMeter=0;
head.biYPelsPerMeter=0;
//写位图信息头进内存
fwrite(&head, sizeof(BITMAPINFOHEADER),1, fp);
//灰度图像,有颜色表,写入文件
RGBQUAD colortable[256];
for (int i=0;i<256;++i)
{
colortable[i].rgbBlue=i;
colortable[i].rgbGreen=i;
colortable[i].rgbRed=i;
colortable[i].rgbReserved=0;
}
RGBQUAD* pColorTable1=colortable;
fwrite(pColorTable1, sizeof(RGBQUAD),256, fp);
//写位图数据进文件
fwrite(ptempimageBuf, imageheight*lineByte, 1, fp);
//关闭文件
fclose(fp);
delete []ptempimageBuf;
return 1;
}
以下是生成的8位bmp
原图