DIB真彩色灰度化问题
请教一下VC++图象处理方面的一个问题,我要把真彩色图象灰度化,下面是好多人在网上相互传的代码,这段代码我看得懂,里面存有许多的问题::DIBWidth(lpDIB)比方说这里用了双::意思是调用SDK函数的意思,但这个函数并不存在,但是我看过这放面的书,其实这个函数是别人编的一个关于DIB的类中的一个函数,只要把这个类的头文件加进去就可以使用了,我先不说这些表面上的错误.一个DIB图象如果要灰度化,首先要加入一个色彩表,然后把象素数据进行灰度化修改,另外一些位图头文件如BITMAPFILEHEADER,BITMAPINFOHEADER里的文件长度,象素位数、偏移量都要加以改变,但以前的DIB图象是真彩色的,图象数据区是RGB分量都有的,是灰度化数据的3倍,灰度化后的数据只用一位就可以表示,下面的程序只是对数据进行了连续修改,可是剩下的2倍大小的图像数据区怎么处理呢?
我感觉这个程序很有问题,我都不知道他们怎么用的。。。。。
* 函数名称:
* ConvertToGrayScale()
*
* 参数:
* LPSTR lpDIB - 指向源DIB图像指针
*
* 返回值:
* bool - 成功返回true,否则返回false。
*
* 说明:
* 该函数将24位真彩色图转换成256级灰度图
*
************************************************************************/
bool WINAPI ConvertToGrayScale(LPSTR lpDIB)
{
LPSTR lpDIBBits; //指向DIB的象素的指针
LPSTR lpNewDIBBits; //指向DIB灰度图图像(新图像)开始处象素的指针
LONG lLineBytes;
unsigned char * lpSrc; //指向原图像象素点的指针
unsigned char * lpdest; //指向目标图像象素点的指针
unsigned char *ired,*igreen,*iblue;
long lWidth; //图像宽度和高度
long lHeight;
long i,j; //循环变量
lWidth = ::DIBWidth(lpDIB); //DIB 宽度
lHeight = ::DIBHeight(lpDIB); //DIB 高度
RGBQUAD *lpRGBquad;
lpRGBquad = (RGBQUAD *)&lpDIB[sizeof(BITMAPINFOHEADER)]; //INFOHEADER后为调色板
if(::DIBNumColors(lpDIB) == 256) //256色位图不作任何处理
{
return true;
}
if(::DIBNumColors(lpDIB) != 256) //非256色位图将它灰度化
{
lLineBytes = WIDTHBYTES(lWidth*8*3);
lpdest= new BYTE[lHeight*lWidth];
lpDIBBits = (LPSTR)lpDIB + sizeof(BITMAPINFOHEADER);//指向DIB象素
for(i = 0;i < lHeight; i++)
for(j = 0;j < lWidth*3; j+=3)
{
ired = (unsigned char*)lpDIBBits + lLineBytes * i + j + 2;
igreen = (unsigned char*)lpDIBBits + lLineBytes * i + j + 1;
iblue = (unsigned char*)lpDIBBits + lLineBytes * i + j ;
//lpdest[i*lWidth + j/3] = (unsigned char)((*ired)*0.299 + (*igreen)*0.588 + (*iblue)*0.114);
lpdest[i*lWidth + j/3] = (unsigned char)((*ired)*0.299 + (*igreen)*0.587 + (*iblue)*0.114);
}
//需要做三件事情:1、修改INFOHEADER 2、增加调色板 3、修改原图像灰度值
LPBITMAPINFOHEADER lpBI;
lpBI = (LPBITMAPINFOHEADER)lpDIB;
lpBI->biBitCount = 8;
//设置灰度调色板
for(i = 0;i < 256;i++)
{
lpRGBquad[i].rgbRed = (unsigned char)i;
lpRGBquad[i].rgbGreen = (unsigned char)i;
lpRGBquad[i].rgbBlue = (unsigned char)i;
lpRGBquad[i].rgbReserved = 0;
}
lpNewDIBBits= ::FindDIBBits(lpDIB); //找到DIB图像象素起始位置
lLineBytes=WIDTHBYTES(lWidth * 8);
//修改灰度值
for(i = 0;i < lHeight; i++)
for(j = 0;j < lWidth; j++)
{
lpSrc = (unsigned char*)lpNewDIBBits + lLineBytes * i+ j ;
*lpSrc=lpdest[i*lWidth+j];
}
delete lpdest;
}
return true;
}