?? vc++開發輪廓跟蹤源程序.txt
字號:
VC++開發輪廓跟蹤源程序
源程序如下,其中函數IsContourP 用來判斷某點是不是邊界點。
BOOL Contour(HWND hWnd)
{
DWORD OffBits,BufSize;
LPBITMAPINFOHEADER lpImgData;
LPSTR lpPtr;
HLOCAL hTempImgData;
LPBITMAPINFOHEADER lpTempImgData;
LPSTR lpTempPtr;
HDC hDc;
HFILE hf;
LONG x,y;
POINT StartP,CurP;
BOOL found;
int i;
int direct[8][2]={{1,0},{1,-1},{0,-1},{-1,-1},{-1,0},
{-1,1},{0,1},{1,1}};
//我們處理的實際上是256 級灰度圖,不過只用到了0 和255 兩種顏色。
if( NumColors!=256){
MessageBox(hWnd,"Must be a mono bitmap with grayscale palette!","Error
Message",MB_OK|MB_ICONEXCLAMATION);
return FALSE;
}
//到位圖數據的偏移值
OffBits=bf.bfOffBits-sizeof(BITMAPFILEHEADER);
//緩沖區大小
BufSize=bf.bfSize-sizeof(BITMAPFILEHEADER);
//為新圖緩沖區分配內存
if((hTempImgData=LocalAlloc(LHND,BufSize))==NULL)
{
MessageBox(hWnd,"Error alloc memory!","Error Message",MB_OK|
MB_ICONEXCLAMATION);
return FALSE;
}
lpImgData=(LPBITMAPINFOHEADER)GlobalLock(hImgData);
lpTempImgData=(LPBITMAPINFOHEADER)LocalLock(hTempImgData);
//新圖緩沖區初始化為255
memset(lpTempImgData,(BYTE)255,BufSize);
//拷貝頭信息
memcpy(lpTempImgData,lpImgData,OffBits);
//找到標志置為假
found=FALSE;
for (y=0;y<bi.biHeight && !found; y++){
lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes);
for (x=0;x<bi.biWidth && !found; x++)
if (*(lpPtr++) ==0) found=TRUE; //找到了最左上的黑點,一定是個邊界點
}
if(found){ //如果找到了,才做處理
//從上面的循環退出時,x,y 坐標都做了加1 的操作。在這里把它們減1,得到起
//始點坐標StartP
StartP.x=x-1;
StartP.y=y-1;
lpTempPtr=(char *)lpTempImgData+(BufSize-
LineBytes-StartP.y*LineBytes)+StartP.x;
*lpTempPtr=(unsigned char)0; //起始點涂黑
//右鄰點
CurP.x=StartP.x+1;
CurP.y=StartP.y;
lpPtr=(char *)lpImgData+(BufSize-LineBytes-CurP.y*LineBytes)+CurP.x;
if(*lpPtr!=0){ //若右鄰點為白,則找右下鄰點
CurP.x=StartP.x+1;
CurP.y=StartP.y+1;
lpPtr=(char *)lpImgData+(BufSize-LineBytes-CurP.y*LineBytes)+CurP.x;
if(*lpPtr!=0){ //若仍為白,則找下鄰點
CurP.x=StartP.x;
CurP.y=StartP.y+1;
}
else{ //若仍為白,則找左下鄰點
CurP.x=StartP.x-1;
CurP.y=StartP.y+1;
}
}
while (! ( (CurP.x==StartP.x) &&(CurP.y==StartP.y))){
//知道找到起始點,循環才結束
lpTempPtr=(char *)lpTempImgData+(BufSize-LineBytes
-CurP.y*LineBytes)+CurP.x;
*lpTempPtr=(unsigned char)0;
for(i=0;i<8;i++){
//按右,右上,上,左上,左,左下,下,右下的順序找相鄰點
//direct[i]中存放的是該方向x,y 的偏移值
x=CurP.x+direct[i][0];
y=CurP.y+direct[i][1];
//lpPtr 指向原圖數據,lpTempPtr 指向新圖數據
lpTempPtr=(char *)lpTempImgData
+(BufSize-LineBytes-y*LineBytes)+x;
lpPtr=(char *)lpImgData+(BufSize-LineBytes-y*LineBytes)+x;
if( ( (*lpPtr==0)&&(*lpTempPtr!=0) ) ||
( (x==StartP.x) &&(y==StartP.y)))
//原圖中為黑點,且新圖中為白點(表示還沒搜索過)時才處理
//另一種可能是找到了起始點
if(IsContourP(x,y,lpPtr)){ //若是個邊界點
//記住當前點的位置
CurP.x=x;
CurP.y=y;
break;
}
}
}
}
if(hBitmap!=NULL)
DeleteObject(hBitmap);
hDc=GetDC(hWnd);
//創立一個新的位圖
hBitmap=CreateDIBitmap(hDc,(LPBITMAPINFOHEADER)lpTempImgData,
(LONG)CBM_INIT,(LPSTR)lpTempImgData+sizeof(BITMAPINFOHEADER) +
NumColors*sizeof(RGBQUAD),(LPBITMAPINFO)lpTempImgData, DIB_RGB_COLORS);
hf=_lcreat("c:\\contour.bmp",0);
_lwrite(hf,(LPSTR)&bf,sizeof(BITMAPFILEHEADER));
_lwrite(hf,(LPSTR)lpTempImgData,BufSize);
_lclose(hf);
//釋放內存和資源
ReleaseDC(hWnd,hDc);
LocalUnlock(hTempImgData);
LocalFree(hTempImgData);
GlobalUnlock(hImgData);
return TRUE;
}
//判斷某點是不是邊界點,參數x,y 為該點的坐標,lpPtr 為指向原位圖數據的指針
BOOL IsContourP(LONG x,LONG y, char *lpPtr)
{
int num,n,w,e,s;
n=(unsigned char)*(lpPtr+LineBytes); //上鄰點
w=(unsigned char)*(lpPtr-1); //左鄰點
e=(unsigned char)*(lpPtr+1); //右鄰點
s=(unsigned char)*(lpPtr-LineBytes); //下鄰點
num=n+w+e+s;
if(num==0) //全是黑點,說明是個內部點而不是邊界點
return FALSE;
return TRUE;
}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -