📄 convertogray.cpp
字号:
#include "StdAfx.h"
#include ".\convertogray.h"
CConverToGray::CConverToGray(void)
{
}
CConverToGray::~CConverToGray(void)
{
}
HBITMAP 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=256; //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)
{
AfxMessageBox("Error alloc memory!",MB_OK|MB_ICONEXCLAMATION);
return NULL;
}
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 hBitmap;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -