版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qq_33001647/article/details/84541634
事情比较多比较杂,早点把学校的事弄完吧,好久没写博客了,最近计算机前沿这门课,老师要布置课题,大部分是Verilog HDL程序设计,脑壳疼,硬件太烦,
不过还好,可以选择其他方向的
哈哈,api学习还是有必要的,不必造轮子,不过,要有造轮子的能力,具体分的课题是边缘检测算法的Robert算子
书上只是给个函数,可以理解为伪代码,具体实现,还是要自己去动手的,书上只是给个思路而已:
核心就是对像素的处理,获取位图像素位,处理像素位,设置像素位,就这么几部,当初想,多么简单啊,其实还是不能大意,遇到一些问题,然后慢慢克服,最终解决难题,只有这样,才能不断成长,绝对不能眼高手低
主要遇到的问题,就是获得位图的像素位
一开始,我以为BITMAP结构的bmBits就是存放像素位的,结果运行有问题
还以为是我自己没有新加载一个位图,在新位图里存放新像素位,结果还是不行,调试时发现BITMAP的bmBits始终为0
所以问题出在这,我们并没有真正获取到位图的像素位,要获取位图的像素位,可以用GetBitmapBits函数,函数怎么用去查msdn或者百度
相应的设置像素位用SetBitmapBits,下面就是Robert算子具体实现的核心代码了
最后实现效果:
好了,大功告成,一定要注意,获取设置位图像素位,用BITMAP的bmBits成员是不行的,用GetBitmapBits和SetBitmapBits即可
最后附上完整win32 API代码:
//VC++图像处理程序
//图像的边缘检测-Robert算子
# include<windows.h>
# include<cmath>
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);//窗口过程函数
void RobertOperator(HDC hdc, HDC hMemDc, HBITMAP hBitmap, int Width, int Height);
int WINAPI WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
PSTR szCmdLine,
int iCmdShow)
{
TCHAR szAppName[] = TEXT("Robert算子");
//设计窗口类
WNDCLASS wndclass;//窗口类
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = 0;
wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH);//窗口背景画刷(白色)
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hInstance = NULL;
wndclass.lpfnWndProc = WndProc;
wndclass.lpszClassName = szAppName;//类名
wndclass.lpszMenuName = NULL;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
//注册窗口类
if (!RegisterClass(&wndclass))
{
MessageBox(NULL, TEXT("Program requires windows NT!"), szAppName, MB_ICONERROR);
return 0;
}
//创建窗口
HWND hwnd = CreateWindow(szAppName,
TEXT("Robert算子"),
WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT,
CW_USEDEFAULT,
540,
630,
NULL,
NULL,
hInstance,
NULL);
ShowWindow(hwnd, SW_SHOW);
UpdateWindow(hwnd);
MSG msg;//消息循环
while (GetMessage(&msg, NULL, 0, 0))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return 0;
}
LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
{
static HDC hMemDc;
static int xWidth, yHeight;
static BITMAP bm;
static HBITMAP hBitmap;
switch (uMsg)
{
case WM_CREATE:
{
//原位图
hBitmap= (HBITMAP)LoadImage(NULL, TEXT("Picture2.bmp"), IMAGE_BITMAP, 0, 0, LR_LOADFROMFILE);
if (hBitmap == NULL)
{
MessageBox(NULL, TEXT("读取图片失败"), TEXT("Error"), MB_ICONERROR);
return 0;
}
//将原位图选进内存DC
HDC hdc = GetDC(hwnd);
hMemDc = CreateCompatibleDC(hdc);//内存DC
SelectObject(hMemDc, hBitmap);
ReleaseDC(hwnd, hdc);
//计算位图的宽和高
GetObject(hBitmap, sizeof(bm), &bm);
xWidth = bm.bmWidth;
yHeight = bm.bmHeight;
return 0;
}
case WM_PAINT:
{
HDC hdc;
PAINTSTRUCT ps;
hdc = BeginPaint(hwnd, &ps);
BitBlt(hdc, 0, 0, xWidth, yHeight, hMemDc, 0, 0, SRCCOPY);
//BitBlt(hdc, 0, 300, xTempWidth, yTempHeight, hTempMemDc, 0, 0, SRCCOPY);
RobertOperator(hdc, hMemDc,hBitmap,xWidth, yHeight);
//BitBlt(hdc, 590, 0, xWidth, yHeight, hMemDc, 0, 0, SRCCOPY);
EndPaint(hwnd, &ps);
return 0;
}
case WM_CLOSE:
DeleteDC(hMemDc);
PostQuitMessage(0);
//DestroyWindow(hwnd);
return 0;
}
return DefWindowProc(hwnd, uMsg, wParam, lParam);
}
void RobertOperator(HDC hdc, HDC hMemDc,HBITMAP hBitmap,int Width, int Height)
{
int Robert_Pixel[4];//Robert算子
BYTE *pTempPixel = new BYTE[16*Width*Height];
//得到位图的像素位
GetBitmapBits(hBitmap,16*Width*Height,(LPVOID)pTempPixel);
BYTE *pPixel = new BYTE[16*Width*Height];
for(int j=0;j<4*Height-1;j++)
for (int i = 0; i < 4*Width - 1; i++)
{
//生成Robert算子
Robert_Pixel[0] = pTempPixel[j*4*Width+i];
Robert_Pixel[1] = pTempPixel[j*4*Width+ i + 1];
Robert_Pixel[2] = pTempPixel[(j + 1)*4*Width+ i];
Robert_Pixel[3] = pTempPixel[(j + 1)*4*Width+i + 1];
//生成当前像素
pPixel[j*4*Width+i] = (int)sqrt((Robert_Pixel[0] - Robert_Pixel[3])*
(Robert_Pixel[0] - Robert_Pixel[3]) + (Robert_Pixel[1] - Robert_Pixel[2])*
(Robert_Pixel[1] - Robert_Pixel[2]));
//pPixel[j*Width + i] = pTempPixel[j*Width + i] + 100;
}
//设置新像素位
SetBitmapBits(hBitmap,16* Width*Height,pPixel);
BitBlt(hdc,0, 300, Width, Height, hMemDc, 0, 0, SRCCOPY);
}
注意相应的位图文件要放在工程目录下,以及位图的文件名