- UID
- 1
- 精华
- 积分
- 76361
- 威望
- 点
- 宅币
- 个
- 贡献
- 次
- 宅之契约
- 份
- 最后登录
- 1970-1-1
- 在线时间
- 小时
|
原理很简单,就是把一个图像横着模糊一下,然后把这个横向模糊过的图像再纵向模糊一下,就是高斯模糊了。
- #include<Windows.h>
- #include<stdlib.h>
- #define 模糊程度 32
- typedef struct
- {
- HINSTANCE hInst;
- HWND hWnd;
- HDC hWindowDC;
- //原图
- HDC hImgDC;
- HBITMAP hImgBmp;
-
- //原图信息
- BITMAP ImgBmp;
- LONG BmpWidth;
- LONG BmpHeight;
- //横向模糊过的图
- HDC hDrawPad1DC;
- HBITMAP hDrawPad1Bmp;
- void*pDrawPad1Bits;
- //最终图
- HDC hFinalDrawPadDC;
- HBITMAP hFinalDrawPadBmp;
- void*pFinalDrawPadBits;
- }GaussianDemo_t,*GaussianDemo_p;
- //============================================================================
- //函数:ShowLastError
- //描述:弹出对话框显示GetLastError的文本信息
- //----------------------------------------------------------------------------
- void ShowLastError(HWND hWnd)
- {
- LPVOID lpMsgBuf;
- FormatMessage
- (
- FORMAT_MESSAGE_ALLOCATE_BUFFER | //返回一个已分配的内存
- FORMAT_MESSAGE_FROM_SYSTEM | //系统消息
- FORMAT_MESSAGE_IGNORE_INSERTS, //无视插入信息
- NULL,
- GetLastError(),
- 0, //默认语言
- (LPTSTR)&lpMsgBuf, //错误信息指针
- 0,
- NULL
- );
- MessageBox(hWnd,(LPCTSTR)lpMsgBuf,NULL,MB_OK|MB_ICONINFORMATION);
- LocalFree(lpMsgBuf);//释放内存
- }
- //============================================================================
- //函数:Create24BitDIBBmp
- //描述:在内存中生成一个空的24位位图,用作“画板”
- //----------------------------------------------------------------------------
- HBITMAP Create24BitDIBBmp(HDC hDC,UINT Width,UINT Height,void**ppBits)
- {
- BITMAPINFOHEADER BMIF={sizeof(BITMAPINFOHEADER),Width,Height,1,24,0,0,0,0,0,0};
- return CreateDIBSection(hDC,(LPBITMAPINFO)&BMIF,DIB_PAL_COLORS,ppBits,
- NULL,0);
- }
- //============================================================================
- //函数:DrawGaussianBlur
- //描述:生成高斯模糊图
- //----------------------------------------------------------------------------
- void DrawGaussianBlur(GaussianDemo_p pData,LONG BlurSize)
- {
- LONG x,y;
- BLENDFUNCTION bf;
- LONG BlurOffset=BlurSize;
- bf.BlendOp=AC_SRC_OVER;
- bf.BlendFlags=0;
- bf.AlphaFormat=0;
- BlurSize*=2;
- //第一步:将图像横着模糊一遍,然后存入第一个画板
- for(x=0;x<BlurSize;x++)
- {
- bf.SourceConstantAlpha=(BYTE)(255/(x+1));
- AlphaBlend(pData->hDrawPad1DC,x-BlurOffset,0,pData->BmpWidth,pData->BmpHeight,
- pData->hImgDC,0,0,pData->BmpWidth,pData->BmpHeight,bf);
- }
- //第二步:将画板中横着模糊的图片再纵向模糊一下,然后存入最终画板
- for(y=0;y<BlurSize;y++)
- {
- bf.SourceConstantAlpha=(BYTE)(255/(y+1));
- AlphaBlend(pData->hFinalDrawPadDC,0,y-BlurOffset,pData->BmpWidth,pData->BmpHeight,
- pData->hDrawPad1DC,0,0,pData->BmpWidth,pData->BmpHeight,bf);
- }
- }
- //============================================================================
- //函数:DeleteDrawPad
- //描述:删除画板
- //----------------------------------------------------------------------------
- void DeleteDrawPad(GaussianDemo_p pData)
- {
- if(pData->hImgBmp)DeleteObject(pData->hImgBmp);
- pData->hImgBmp=NULL;
- if(pData->hDrawPad1Bmp)DeleteObject(pData->hDrawPad1Bmp);
- pData->hDrawPad1Bmp=NULL;
- if(pData->hFinalDrawPadBmp)DeleteObject(pData->hFinalDrawPadBmp);
- pData->hFinalDrawPadBmp=NULL;
- if(pData->hImgDC)DeleteDC(pData->hImgDC);
- pData->hImgDC=NULL;
- if(pData->hDrawPad1DC)DeleteDC(pData->hDrawPad1DC);
- pData->hDrawPad1DC=NULL;
- if(pData->hFinalDrawPadDC)DeleteDC(pData->hFinalDrawPadDC);
- pData->hFinalDrawPadDC=NULL;
- }
- //============================================================================
- //函数:SetupDrawPad
- //描述:设置画板,用于绘制高斯模糊图
- //----------------------------------------------------------------------------
- BOOL SetupDrawPad(GaussianDemo_p pData)
- {
- HWND hWnd=pData->hWnd;
- //分析位图
- GetObject(pData->hImgBmp,sizeof(pData->ImgBmp),&(pData->ImgBmp));
- //取得尺寸
- pData->BmpWidth=pData->ImgBmp.bmWidth;
- if(pData->ImgBmp.bmHeight<0)
- pData->BmpHeight=-pData->ImgBmp.bmHeight;
- else
- pData->BmpHeight=pData->ImgBmp.bmHeight;
- SelectObject(pData->hImgDC,pData->hImgBmp);
- //创建第一个画板
- if(pData->hDrawPad1Bmp)DeleteObject(pData->hDrawPad1Bmp);
- pData->hDrawPad1Bmp=Create24BitDIBBmp(pData->hDrawPad1DC,
- pData->BmpWidth,pData->BmpHeight,&(pData->pDrawPad1Bits));
- if(!pData->hDrawPad1Bmp)
- {
- ShowLastError(hWnd);
- DeleteDrawPad(pData);
- return FALSE;
- }
- SelectObject(pData->hDrawPad1DC,pData->hDrawPad1Bmp);//组装
- //创建第二个画板
- if(pData->hFinalDrawPadBmp)DeleteObject(pData->hFinalDrawPadBmp);
- pData->hFinalDrawPadBmp=Create24BitDIBBmp(pData->hFinalDrawPadDC,
- pData->BmpWidth,pData->BmpHeight,&(pData->pFinalDrawPadBits));
- if(!pData->hFinalDrawPadBmp)
- {
- ShowLastError(hWnd);
- DeleteDrawPad(pData);
- return FALSE;
- }
- SelectObject(pData->hFinalDrawPadDC,pData->hFinalDrawPadBmp);
- return TRUE;
- }
- //============================================================================
- //函数:LoadPictureFileA
- //描述:加载一个图像文件,并生成高斯模糊图
- //----------------------------------------------------------------------------
- BOOL LoadPictureFileA(CHAR*szFileName,GaussianDemo_p pData)
- {
- HWND hWnd=pData->hWnd;
- //加载文件
- if(pData->hImgBmp)DeleteObject(pData->hImgBmp);
- pData->hImgBmp=(HBITMAP)LoadImageA(NULL,szFileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
- if(!pData->hImgBmp)
- {
- if(!GetLastError())
- MessageBox(hWnd,TEXT("不是bmp文件。"),NULL,MB_OK|MB_ICONINFORMATION);
- else
- ShowLastError(hWnd);
- DeleteDrawPad(pData);
- return FALSE;
- }
- //设置好画板就进行模糊处理
- SetupDrawPad(pData);
- DrawGaussianBlur(pData,模糊程度);
- return TRUE;
- }
- BOOL LoadPictureFileW(WCHAR*szFileName,GaussianDemo_p pData)
- {
- HWND hWnd=pData->hWnd;
- //加载文件
- if(pData->hImgBmp)DeleteObject(pData->hImgBmp);
- pData->hImgBmp=(HBITMAP)LoadImageW(NULL,szFileName,IMAGE_BITMAP,0,0,LR_LOADFROMFILE);
- if(!pData->hImgBmp)
- {
- if(!GetLastError())
- MessageBox(hWnd,TEXT("不是bmp文件。"),NULL,MB_OK|MB_ICONINFORMATION);
- else
- ShowLastError(hWnd);
- DestroyWindow(hWnd);
- DeleteDrawPad(pData);
- return FALSE;
- }
- //设置好画板就进行模糊处理
- SetupDrawPad(pData);
- DrawGaussianBlur(pData,模糊程度);
- return TRUE;
- }
- #ifdef UNICODE
- #define LoadPictureFile LoadPictureFileW
- #else
- #define LoadPictureFile LoadPictureFileA
- #endif
- LRESULT CALLBACK WndProc(HWND hWnd,UINT Msg,WPARAM wp,LPARAM lp)
- {
- GaussianDemo_p pUserData;
- switch(Msg)
- {
- case WM_CREATE:
- //创建窗口的时候设置窗口的属性和附加的内容
- //接收文件拖放
- DragAcceptFiles(hWnd,TRUE);
- //附加内容
- pUserData=(GaussianDemo_p)malloc(sizeof(GaussianDemo_t));
- if(!pUserData)
- return -1;
- //填写附加内容
- memset(pUserData,0,sizeof(GaussianDemo_t));
- pUserData->hInst=GetModuleHandle(NULL);
- pUserData->hWnd=hWnd;
- pUserData->hImgDC=CreateCompatibleDC(pUserData->hWindowDC=GetWindowDC(hWnd));
- pUserData->hDrawPad1DC=CreateCompatibleDC(pUserData->hWindowDC);
- pUserData->hFinalDrawPadDC=CreateCompatibleDC(pUserData->hWindowDC);
- //设置附加内容
- SetWindowLongPtr(hWnd,GWLP_USERDATA,(LONG_PTR)pUserData);
- if(__argc>1)
- LoadPictureFileA(__argv[1],pUserData);
- break;
- case WM_DROPFILES:
- {
- TCHAR szFile[MAX_PATH];
- RECT rc;
- //取得窗口附加信息
- pUserData=(GaussianDemo_p)GetWindowLongPtr(hWnd,GWLP_USERDATA);
- //取得拖拽入的文件名
- DragQueryFile((HDROP)wp,0,szFile,MAX_PATH);
- LoadPictureFile(szFile,pUserData);
- GetClientRect(hWnd,&rc);
- InvalidateRect(hWnd,&rc,TRUE);
- }
- break;
- case WM_PAINT:
- {
- HDC hPaintDC;
- RECT rc;
- PAINTSTRUCT ps;
- GetClientRect(hWnd,&rc);
- //取得窗口附加信息
- pUserData=(GaussianDemo_p)GetWindowLongPtr(hWnd,GWLP_USERDATA);
- hPaintDC=BeginPaint(hWnd,&ps);
- BitBlt(hPaintDC,0,0,rc.right-rc.left,rc.bottom-rc.top,pUserData->hFinalDrawPadDC,0,0,SRCCOPY);
- EndPaint(hWnd,&ps);
- }
- break;
- case WM_DESTROY:
- pUserData=(GaussianDemo_p)GetWindowLongPtr(hWnd,GWLP_USERDATA);
- DeleteDrawPad(pUserData);
- free(pUserData);
- SetWindowLongPtr(hWnd,GWLP_USERDATA,(LONG_PTR)NULL);
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hWnd,Msg,wp,lp);
- }
- return 0;
- }
- void CreateInst(HINSTANCE hInst,int ShowCmd)
- {
- WNDCLASSEX WCEx={sizeof(WNDCLASSEX),0,WndProc,0,0,hInst,LoadIcon(NULL,MAKEINTRESOURCE(IDI_APPLICATION)),LoadCursor(NULL,MAKEINTRESOURCE(IDC_ARROW)),(HBRUSH)COLOR_BTNFACE,NULL,TEXT("tuttb"),NULL};//窗口类
- HWND hWnd=CreateWindowEx(0,MAKEINTATOM(RegisterClassEx(&WCEx)),TEXT("请将文件拖拽进来"),WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT,CW_USEDEFAULT,400,300,NULL,NULL,hInst,NULL);//窗口句柄
- ShowWindow(hWnd,ShowCmd);
- UpdateWindow(hWnd);
- }
- int APIENTRY WinMain(HINSTANCE hInst,HINSTANCE hPrevInst,LPSTR szCmd,int ShowCmd)
- {
- MSG msg;
- CreateInst(hInst,ShowCmd);
- while(GetMessage(&msg,NULL,0,0))//消息循环
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- return msg.wParam;
- }
复制代码
SRC:
简单高斯模糊.7z
(234.7 KB, 下载次数: 22)
BIN:
简单高斯模糊Bin.7z
(230.41 KB, 下载次数: 23)
|
|