首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 平面设计 > 图形图像 >

24位bmp彩色图片转换为8位灰度图像异常

2013-03-21 
24位bmp彩色图片转换为8位灰度图像错误/*** 程序名: Convert.cpp* 功能: 将24位真彩色图转换为8位灰度图片

24位bmp彩色图片转换为8位灰度图像错误


/**
* 程序名: Convert.cpp
* 功  能: 将24位真彩色图转换为8位灰度图片
*  测试图片test1.bmp放到工程目录下
*/
#include <iostream>
#include <fstream>
#include <windows.h>
#include <cstring>
using namespace std;
BITMAPFILEHEADER bmpFileHeader; //位图文件头
BITMAPINFOHEADER bmpInfoHeader; //位图信息头
RGBQUAD *pColorTable;//颜色表,注:24位真彩色图无颜色表
unsigned char *pBmpData;//位图数据
unsigned char *pGrayData;//灰度图像数据
/**
* 函数名: readBmp
* 参  数: fileName -- 要转换的图片名
* 功  能: 读取fileName文件信息,读取成功返回TRUE,反之,返回FALSE
*/
bool readBmp(char *fileName)
{
FILE *fp = fopen(fileName,"rb");//以二进制读方式打开
if(NULL == fp)
{
cout<<"File is opened failure!"<<endl;
return FALSE;
}
//读取数据
fread(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
fread(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);
pBmpData = new unsigned char[bmpInfoHeader.biSizeImage];   //申请空间,大小为位图数据大小
fread(pBmpData,sizeof(unsigned char),bmpInfoHeader.biSizeImage,fp);
fclose(fp);//不要忘了关闭文件
return TRUE;
}
/**
* 函数名: convert
* 功  能: 实现24位真彩色图到灰度图的转换
*/
void convert()
{
//因为转换后多了个颜色表,所以要改变,对bmp文件结构不清楚的看笔记1
bmpFileHeader.bfOffBits += (sizeof(RGBQUAD) * 256); 
 //biSizeImg存储的为位图数据占用的字节数,转换为灰度图像后值发生改变,
//因为24为真彩色位图数据的一个像素用3各字节表示,灰度图像为1个字节
bmpInfoHeader.biBitCount = 8;
int lineBytes = (bmpInfoHeader.biWidth * 8 + 31) / 32 * 4;
int oldSize = bmpInfoHeader.biSizeImage;//原图数据大小
bmpInfoHeader.biSizeImage = lineBytes * bmpInfoHeader.biHeight;
//定义灰度图像的颜色表
pColorTable = new RGBQUAD[256];
for(int i = 0; i < 256; i++ )
{
(*(pColorTable + i)).rgbBlue = i;
(*(pColorTable + i)).rgbGreen = i;
(*(pColorTable + i)).rgbRed = i;
(*(pColorTable + i)).rgbReserved = 0;
}
//将RGB转换为灰度值
int red,green,blue;
BYTE gray;
pGrayData = new unsigned char[bmpInfoHeader.biSizeImage];
int k = 0,j;
memset(pGrayData,(BYTE)255,bmpInfoHeader.biSizeImage);
cout<<bmpInfoHeader.biWidth<<endl;
cout<<lineBytes<<endl;

for( j = 0; j < oldSize; j += 3 )
{
red = *(pBmpData + j );
green = *(pBmpData + j + 1);
blue = *(pBmpData + j + 2);
gray = (BYTE)((77 * red + 151 * green + 28 * blue) >> 8);
*(pGrayData + k++) = gray;
}

}
/**
* 函数名: writeBmp
* 参  数: fileName -- 转换之后的文件名
* 功  能: 将转换后的图像信息写入到fileName文件中
*/
bool writeBmp(char *fileName)
{
FILE *fp = fopen(fileName,"wb");   //以二进制写方式打开
if(NULL == fp)
{
cout<<"File is opened failure!"<<endl;
return FALSE;
}
//写入数据
fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,fp);
fwrite(&bmpInfoHeader,sizeof(BITMAPINFOHEADER),1,fp);


fwrite(pColorTable,sizeof(RGBQUAD),256,fp);
fwrite(pGrayData,sizeof(unsigned char),bmpInfoHeader.biSizeImage,fp);
fclose(fp);
//释放内存空间
delete []pColorTable;
delete []pBmpData;
delete []pGrayData;
return TRUE;
}
/**
* 函数名: work
* 功  能: 主要处理步骤
*/
void work()
{
char readFileName[] = "test1.bmp";
if(!readBmp(readFileName))
cout<<"The function of readBmp error!"<<endl;
convert();
char writeFileName[] = "gray.bmp";
if(!writeBmp(writeFileName))
cout<<"The function of writebmp error!"<<endl;

}
int main()
{
work();
return 0;
}


上面的代码不知道是什么问题,转换出的图片总是倾斜的,和原图不一致 vc图像编程
[解决办法]
for(?j?=?0;?j?<?oldSize;?j?+=?3?)
????????{
????????????red?=?*(pBmpData?+?j?);
????????????green?=?*(pBmpData?+?j?+?1);
????????????blue?=?*(pBmpData?+?j?+?2);
????????????gray?=?(BYTE)((77?*?red?+?151?*?green?+?28?*?blue)?>>?8);
????????????*(pGrayData?+?k++)?=?gray;
????????}
中未考虑 bmp 文件数据部分每行中填充的字节。

热点排行