⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 convertogray.cpp

📁 用数字图像处理主要是为了修改图形,改善图像质量,或是从图像中提起有效信息,还有利用数字图像处理可以对图像进行体积.
💻 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 + -