彩色图到灰度图的转换
BOOL ColortoGrayScale(HWND hWnd)
{
DWORD SrcBufSize,DstBufSize,DstLineBytes;
LPBITMAPINFOHEADER lpImgData;
LPSTR lpPtr;
HLOCAL hTempImgData;
LPBITMAPINFOHEADER lpTempImgData;
LPSTR lpTempPtr;
HDC hDc;
HFILE hf;
LONG x,y;
BITMAPFILEHEADER DstBf;
BITMAPINFOHEADER DstBi;
LOGPALETTE *pPal;
HPALETTE hPrevPalette;
HLOCAL hPal;
DWORD NewNumColors;
WORD NewBitCount;
float Y;
DWORD i;
unsigned char Red,Green,Blue,Gray;
NewNumColors=NumColors; //NewNumColors为新图的颜色数
NewBitCount=bi.biBitCount; //NewBitCount为新图的颜色位数
if(NumColors==0) //真彩图
{
NewNumColors=256;
NewBitCount=8;
}
//由于颜色位数有可能发生了改变,所以要重新计算每行占用的字节数以及新图
//的缓冲区大小
DstLineBytes=(DWORD)WIDTHBYTES(bi.biWidth*NewBitCount);
DstBufSize=(DWORD)(sizeof(BITMAPINFOHEADER)+NewNumColors*
sizeof(RGBQUAD)+(DWORD)DstLineBytes*bi.biHeight);
//DstBf和DstBi为新的BITMAPFILEHEADER和BITMAPINFOHEADER
//拷贝原来的头信息
memcpy((char *)&DstBf,(char *)&bf,sizeof(BITMAPFILEHEADER));
memcpy((char *)&DstBi,(char *)&bi,sizeof(BITMAPINFOHEADER));
//做必要的改变
DstBf.bfSize=DstBufSize+sizeof(BITMAPFILEHEADER);
DstBf.bfOffBits=(DWORD)(NewNumColors*sizeof(RGBQUAD)+
sizeof(BITMAPFILEHEADER)
+sizeof(BITMAPINFOHEADER));
DstBi.biClrUsed=0;
DstBi.biBitCount=NewBitCount;
//原图的缓冲区的大小
SrcBufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
if((hTempImgData=LocalAlloc(LHND,DstBufSize))==NULL)
{
MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|
MB_ICONEXCLAMATION);
return FALSE;
}
lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
//拷贝头信息和位图数据
memcpy(lpTempImgData,lpImgData,DstBufSize);
//用新的BITMAPINFOHEADER替换原来的头信息
memcpy(lpTempImgData,(char *)&DstBi,sizeof(BITMAPINFOHEADER));
//lpPtr指向原图的数据
lpPtr=(char *)lpImgData+sizeof(BITMAPINFOHEADER);
//lpTempPtr指向新图的数据
lpTempPtr=(char *)lpTempImgData+sizeof(BITMAPINFOHEADER);
//为新的调色板分配内存
hPal=LocalAlloc(LHND,sizeof(LOGPALETTE) + NewNumColors
* sizeof(PALETTEENTRY));
pPal =(LOGPALETTE *)LocalLock(hPal);
pPal->palNumEntries =(WORD) NewNumColors;
pPal->palVersion = 0x300;
if(NumColors==0) //真彩色
for (i = 0; i < 256; i++) { //灰度从(0,0,0)到(255,255,255)
pPal->palPalEntry[i].peRed=(BYTE)i;
pPal->palPalEntry[i].peGreen=(BYTE)i;
pPal->palPalEntry[i].peBlue=(BYTE)i;
pPal->palPalEntry[i].peFlags=(BYTE)0;
*(lpTempPtr++)=(unsigned char)i;
*(lpTempPtr++)=(unsigned char)i;
*(lpTempPtr++)=(unsigned char)i;
*(lpTempPtr++)=0;
}
else
for (i = 0; i < NewNumColors; i++) { //带调色板的彩色图
Blue=(unsigned char )(*lpPtr++);
Green=(unsigned char )(*lpPtr++);
Red=(unsigned char )(*lpPtr++);
Y=(float)(Red*0.299+Green*0.587+Blue*0.114);
Gray=(BYTE)Y;
lpPtr++;
//从原来的调色板中的颜色计算得到Y值,写入新的调色板
pPal->palPalEntry[i].peRed=Gray;
pPal->palPalEntry[i].peGreen=Gray;
pPal->palPalEntry[i].peBlue=Gray;
pPal->palPalEntry[i].peFlags=0;
*(lpTempPtr++)=(unsigned char)Gray;
*(lpTempPtr++)=(unsigned char)Gray;
*(lpTempPtr++)=(unsigned char)Gray;
*(lpTempPtr++)=0;
}
if(hPalette!=NULL)
DeleteObject(hPalette);
//生成新的逻辑调色板
hPalette=CreatePalette(pPal);
LocalUnlock(hPal);
LocalFree(hPal);
hDc=GetDC(hWnd);
if(hPalette){
hPrevPalette=SelectPalette(hDc,hPalette,FALSE);
RealizePalette(hDc);
}
if(NumColors==0) //真彩色图才需要处理位图数据
for(y=0;y<bi.biHeight;y++){
lpPtr=(char *)lpImgData+(SrcBufSize-LineBytes-y*LineBytes);
lpTempPtr=(char *)lpTempImgData+(DstBufSize-DstLineBytes-y*DstLineBytes);
for(x=0;x<bi.biWidth;x++){
Blue=(unsigned char )(*lpPtr++);
Green=(unsigned char )(*lpPtr++);
Red=(unsigned char )(*lpPtr++);
Y=(float)(Red*0.299+Green*0.587+Blue*0.114);
//从位图数据计算得到Y值,写入新图中
Gray=(BYTE)Y;
*(lpTempPtr++)=(unsigned char)Gray;
}
}
if(hBitmap!=NULL)
DeleteObject(hBitmap);
//产生新的位图
hBitmap=CreateDIBitmap(hDc, (LPBITMAPINFOHEADER)lpTempImgData,
(LONG)CBM_INIT,
(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +
NewNumColors*sizeof(RGBQUAD),
(LPBITMAPINFO)lpTempImgData, DIB_RGB_COLORS);
if(hPalette && hPrevPalette){
SelectPalette(hDc,hPrevPalette,FALSE);
RealizePalette(hDc);
}
hf=_lcreat("c://gray.bmp",0);
_lwrite(hf,(LPSTR)&DstBf,sizeof(BITMAPFILEHEADER));
_lwrite(hf,(LPSTR)lpTempImgData,DstBufSize);
_lclose(hf);
//释放内存和资源
ReleaseDC(hWnd,hDc);
LocalUnlock(hTempImgData);
LocalFree(hTempImgData);
GlobalUnlock(hImgData);
return TRUE;
}
分享到:
相关推荐
彩色图像与灰度图像间转换的程序设计
将彩色图像转成灰度图像源代码,轻松实现彩色图像向灰度图像的转换。
opencv将彩色图转换为灰度图并保存 src转换为dst保存
基于Qt和OpenCV实现彩色图和灰度图的转换
彩色图像转灰度图的算法,带图形界面,c++写的,比较简单
基于opencv的图像颜色转换,把一帧三通道的彩色图像转换成单通道的灰度图像!
C# 将彩色图片转换为灰度图片C# 将彩色图片转换为灰度图片C# 将彩色图片转换为灰度图片C# 将彩色图片转换为灰度图片C# 将彩色图片转换为灰度图片
完整代码,可直接运行
基于opencv的彩色图变灰度图代码,用c++编写的
将彩色图转换为灰度图将彩色图转换为灰度图将彩色图转换为灰度图
本程序是参考网上相关程序后,制作的一个彩色图转灰度图的灰度转换工具。
自己写的批量转换彩色BMP到灰度图像的程序。 批量转换其他格式图片为bmp图片可以用acdSee实现。 经过测试有少量问题存在,不过不影响正常使用。 bmp必须为24位位图。
把彩色图RGB转换为灰度图,适合labview8.0以下版本,
通过新建一个窗体,在窗体中通过按钮事件处理程序,通过内存法、提取像素法和指针法实现,将衣服彩色图像转换为灰度图像。并且可以保存已得到的灰度图像。
用MATLAB实现的很方便的将灰度图转化为彩色图像的源代码。
可以通过一张彩色样本图,将灰度图转换为彩色图,核心思想就是找到灰度图和样本图亮度值相等或者最接近的点,将样本图的颜色值赋给灰度图对应的点得到彩色图。原程序来自Jeny Rajan,后由P.F修改。
此程序实现将256色的bmp图改为灰度图,本人尝试讲24位真彩色图转位256色灰度图,失败,希望大家可以在24位转256灰度上交流。
把灰度图像转化为彩色图像的MATLAB代码。