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

📄 lapls.cpp

📁 用数字图像处理主要是为了修改图形,改善图像质量,或是从图像中提起有效信息,还有利用数字图像处理可以对图像进行体积.
💻 CPP
📖 第 1 页 / 共 2 页
字号:
	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);//把lpImagData的内容拷到lpTempImagData
	//用新的BITMAPINFOHEADER替换原来的头信息
	::memcpy(lpTempImgData,(char*)&DstBi,sizeof(BITMAPINFOHEADER));//把DstBi的内容追加到lpTempImagData
	//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),填充调色板,并填写RGBQUAD结构
			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);
			Y=(float)(Red*0.11+Green*0.59+Blue*0.3);

			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(hpic);
		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=(float)(Red*0.11+Green*0.59+Blue*0.3);

					//从位图数据计算得到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);
			/*CPicture pic;
			pic.ShowPic(hBitmap,hWnd,IDC_PIC_LIB);*/
			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(hpic,hDc);
			LocalUnlock(hTempImgData);
			LocalFree(hTempImgData);
			GlobalUnlock(hImgData);
			return hBitmap;
}
HBITMAP CLapls::MedianFilter(HWND hWnd,BOOL Hori)
{
	DWORD OffBits,BufSize;
	LPBITMAPINFOHEADER lpImgData;
	LPSTR lpPtr;
	HLOCAL hTempImgData;
	LPBITMAPINFOHEADER lpTempImgData;
	LPSTR lpTempPtr;
	HDC hDc;
	HFILE  hf;
	LONG x,y;
	int g,g1,g2,g3;
	//OffBits为BITMAPINFOHEADER结构长度加调色板的大小
	OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);
	BufSize=OffBits+bi.biHeight*LineBytes;//要开的缓冲区的大小
	if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
	{
		AfxMessageBox("Error alloc memory!",MB_OK|MB_ICONEXCLAMATION);
		return NULL;
	}
	lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData); 
	lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
	//拷贝头信息及位图数据
	memcpy(lpTempImgData,lpImgData,BufSize);
	//注意边界点不处理,所以y从1到高度-2,x类似
	for(y=1;y<bi.biHeight-1;y++)
		for(x=1;x<bi.biWidth-1;x++){
			lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+x;
			lpTempPtr=(char*)lpTempImgData+(BufSize-LineBytes-y*LineBytes)+x;
			g2=(unsigned char)*(lpPtr);
			if(Hori==FALSE){ //水平方向
				g1=(unsigned char)*(lpPtr-1); //左邻点
				g3=(unsigned char)*(lpPtr+1); //右邻点
			}
			else{ //垂直方向
				g1=(unsigned char)*(lpPtr+LineBytes); //上邻点
				g3=(unsigned char)*(lpPtr-LineBytes); //下邻点
			}
			//三者取中
			if(g1>g2){
				if(g2>g3) g=g2;
				else{
					if(g1>g3) g=g3;
					else g=g1;
				}
			}
			else{ //g1<=g2
				if(g1>g3) g=g1;
				else{ 
					if(g2>g3) g=g3;
					else g=g2;
				}
			}
			*lpTempPtr=(BYTE)g; //存入新的缓冲区内
		}
		HWND hpic=::GetDlgItem(hWnd,IDC_PIC_LIB);
		hDc=::GetDC(hpic);
		if(hBitmap!=NULL)
			DeleteObject(hBitmap);
		//产生新的位图
		hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,(LONG)CBM_INIT,(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER)+NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData,DIB_RGB_COLORS);
		CPicture pic;
		pic.ShowPic(hBitmap,hWnd,IDC_PIC_LIB); 
		//if(Hori) //取不同的结果文件名
			hf=_lcreat("c:\\median.bmp",0);
		/*else
			hf=_lcreat("c:\\vmedian.bmp",0);*/
		_lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));
		_lwrite(hf,(LPSTR)lpTempImgData,BufSize);
		_lclose(hf);
		//释放内存及资源
		::ReleaseDC(hpic,hDc);
		LocalUnlock(hTempImgData);
		LocalFree(hTempImgData);
		GlobalUnlock(hImgData);
		return hBitmap;
}
BOOL CLapls::Histogram(HWND hWnd, HINSTANCE hInstance)
{	
    DWORD OffBits,BufSize;
	LPBITMAPINFOHEADER lpImagData;
	LPSTR lpPtr;
	int x,y;
	int grayindex;
	HWND hPopupWnd;
	int temp;
	for(grayindex=0;grayindex<256;grayindex++)
		GrayTable[grayindex]=0;
	OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);
	BufSize=OffBits+bi.biHeight*LineBytes;
	lpImagData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
	for(y=0;y<bi.biHeight;y++)
	{
		lpPtr=(char*)lpImagData+(BufSize-LineBytes-y*LineBytes);
		for(x=0;x<bi.biWidth;x++)
		{
			grayindex=(unsigned char)*(lpPtr++);//*(lpPtr)即象素对应调色板的地址,在灰度图里也是灰度值。
			GrayTable[grayindex]++;//grayindex的值即0-256中灰度值
		}
	}
	MaxGrayNum=0;
	MinGrayNum=65535;
	for(grayindex=0;grayindex<256;grayindex++)
	{
		temp=GrayTable[grayindex];
		if(temp>MaxGrayNum)
			MaxGrayNum=temp;
		if(temp<MinGrayNum&&(temp>0))
			MinGrayNum=temp;
	}
	GlobalUnlock(hImgData);	
	wnd=new CWnd;
	wnd->CreateEx(0,AfxRegisterWndClass(0,::LoadCursor(NULL,IDC_ARROW),(HBRUSH)::GetStockObject(WHITE_BRUSH)
		,::LoadIcon(NULL, IDI_APPLICATION)),"histogram",WS_OVERLAPPEDWINDOW,50,80,550,350,hWnd,NULL,NULL);
	hPopupWnd=wnd->GetSafeHwnd();
	if(hPopupWnd)
	{
		OldProc=(WNDPROC)::GetWindowLong(hPopupWnd,GWL_WNDPROC);
		::SetWindowLong(hPopupWnd,GWL_WNDPROC,(LONG)WindowProc);
		::ShowWindow(hPopupWnd,SW_SHOW);
		::UpdateWindow(hPopupWnd);
	}	
	return TRUE;
}

LRESULT CALLBACK WindowProc(HWND hWnd,UINT message,WPARAM wParam,LPARAM lParam)
{
	// TODO: 在此添加专用代码和/或调用基类
	HDC hdc;
	PAINTSTRUCT ps;
	DWORD i;
	int xstart;
	static LOGPEN blp={PS_SOLID,1,1,RGB(0,0,255)};
	HPEN bhp;
	float a,b,temp;
	char str[10];
	a=(float)(265.0/(MaxGrayNum-MinGrayNum));//计算出两个图像比例系数a,b
	b=(float)(270.0-a*MaxGrayNum);	
	if (message==WM_MOVE||message==WM_PAINT||message==WM_NCPAINT||message==WM_NCACTIVATE ||message == WM_NOTIFY)
	{	
		hdc=BeginPaint(hWnd,&ps);
		bhp=CreatePenIndirect(&blp);
		SelectObject(hdc,bhp);
		MoveToEx(hdc,2,270,NULL);
		LineTo(hdc,518,270);
		xstart=2;
		for(i=0;i<256;i++)
		{
			MoveToEx(hdc,xstart,270,NULL);
			if(GrayTable[i]!=0)
				temp=(float)(a*(GrayTable[i])+b);
			else
				temp=0.0f;
			LineTo(hdc,xstart,270-(int)temp);
			if(i%16==0)
			{
				MoveToEx(hdc,xstart,270,NULL);
				LineTo(hdc,xstart,280);
				_itoa(i,str,10);//把整数转换成字符串,把整数i转换成10进制存放在str中
				TextOut(hdc,xstart,285,str,strlen(str));
			}
			xstart+=2;
		}
		MoveToEx(hdc,xstart,270,NULL);
		LineTo(hdc,xstart,280);
		TextOut(hdc,xstart,285,"256",strlen("256"));
		EndPaint(hWnd,&ps);
		DeleteObject(bhp);		
	}
	return CallWindowProc(OldProc,hWnd,message,wParam,lParam); 
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -