`

彩色图到灰度图的转换【未经测试】

 
阅读更多

彩色图到灰度图的转换
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;

}

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics