📄 areapro.cpp
字号:
int nWidthBytes, nNumColors, x, y;
//是否找到起始点及回到起始点
bool bFindStartPoint;
//是否扫描到一个边界点
bool bFindPoint;
//起始边界点与当前边界点
CPoint StartPoint,CurrentPoint;
//八个方向和起始扫描方向
int Direction[8][2]={
{-1, 1},
{ 0, 1},
{ 1, 1},
{ 1, 0},
{ 1,-1},
{ 0,-1},
{-1,-1},
{-1, 0}
};
int BeginDirect;
//原图像指针
pOldBuffer = (unsigned char *) m_pDibObject->GetDIBPointer(&nWidthBytes,
m_pDibObject->GetNumBits() );
if( pOldBuffer == NULL ) return( FALSE );
//原图像文件头指针
pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
//原图像信息头指针
pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
//原图像颜色数
nNumColors = m_pDibObject->GetNumColors();
//原图像调色板指针
pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
//原图像数据指针
pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
+nNumColors*sizeof(RGBQUAD)];
//为新图像数据区分配内存
DWORD dwNewSize;
HGLOBAL hNewDibBits;
//新图像数据区大小
dwNewSize = nWidthBytes * nHeight;
//为新图像分配内存
hNewDibBits = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
if( hNewDibBits == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像指针
pNewBits = (unsigned char *) ::GlobalLock( hNewDibBits );
if( pNewBits == NULL )
{
::GlobalFree( hNewDibBits );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//用255(白色)填充新图像数据区
memset(pNewBits, (BYTE)255, nWidthBytes * nHeight );
//用原图像数据填充新图像数据区
//memcpy( pNewBits, pOldBits, nWidthBytes * nHeight );
//查找最左下方的边界点
bFindStartPoint = false;
for (y = 0; y < nHeight && !bFindStartPoint; y++)
{
pOldTemp = pOldBits;
pOldTemp += y * nWidthBytes;
pNewTemp = pNewBits;
pNewTemp += y * nWidthBytes;
for(x = 0; x < nWidth && !bFindStartPoint; x++)
{
//找到最左上方的边界点
if(pOldTemp[x] == 0)
{
bFindStartPoint = true;
StartPoint.y = y;
StartPoint.x = x;
//新图像数据区相应位置赋0(黑色)
pNewTemp[x] = (unsigned char)0;
}
}
}
//由于起始点是在左下方,故起始扫描沿左上方向
BeginDirect = 0;
//是否跟踪到起始点
bFindStartPoint = false;
//从初始点开始扫描
CurrentPoint = StartPoint;
//边界跟踪
while(!bFindStartPoint)
{
bFindPoint = false;
while(!bFindPoint)
{
//沿扫描方向查看一个像素
pOldTemp = pOldBits + nWidthBytes *
( CurrentPoint.y + Direction[BeginDirect][1])
+ (CurrentPoint.x + Direction[BeginDirect][0]);
if(*pOldTemp == 0)
{
bFindPoint = true;
CurrentPoint.y = CurrentPoint.y +
Direction[BeginDirect][1];
CurrentPoint.x = CurrentPoint.x +
Direction[BeginDirect][0];
if(CurrentPoint == StartPoint)
{
bFindStartPoint = true;
}
pNewTemp = pNewBits + nWidthBytes *
CurrentPoint.y +
CurrentPoint.x;
*pNewTemp = (unsigned char)0;
//扫描的方向逆时针旋转两格
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
}
else
{
//扫描方向顺时针旋转一格
BeginDirect++;
if(BeginDirect == 8)
BeginDirect = 0;
}
}
}
//用新图像数据填充原图像数据区
memcpy( pOldBits, pNewBits, nWidthBytes * nHeight );
::GlobalFree( hNewDibBits );
::GlobalUnlock( m_pDibObject->GetDib() );
return(TRUE);
}
////////////////////////////////////////////////////////////////////////
//BOOL ContourPickUp()
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject图像对象进行轮廓提取。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject 图像对象指针
//----------------------------------------------------------------------
//返 回:BOOL
// 成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CAreaPro::ContourPickUp(CDibObject *pDibObject)
{
//图像指针为空,无法操作返回
if(m_pDibObject == NULL) return(FALSE);
//只支持8位图像
if(m_pDibObject->GetNumBits() != 8)
{
// 提示用户参数设置错误
AfxMessageBox("只支持8位图像,请重新载入!");
// 返回
return( FALSE );
}
//获取图像宽度和高度(以像素为单位)
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//定义变量
unsigned char *pOldBuffer;
unsigned char *pOldBits, *pNewBits;
unsigned char *pOldTemp, *pNewTemp;
BITMAPFILEHEADER *pOldBFH;
BITMAPINFOHEADER *pOldBIH;
RGBQUAD *pOldPalette;
int nWidthBytes, nNumColors, x, y;
//八个方向
unsigned char n,e,s,w,ne,se,nw,sw;
//临时存放像素值
unsigned char pixel;
//原图像指针
pOldBuffer = (unsigned char *) m_pDibObject->GetDIBPointer(&nWidthBytes,
m_pDibObject->GetNumBits() );
if( pOldBuffer == NULL ) return( FALSE );
//原图像文件头指针
pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
//原图像信息头指针
pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
//原图像颜色数
nNumColors = m_pDibObject->GetNumColors();
//原图像调色板指针
pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
//原图像数据指针
pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
+nNumColors*sizeof(RGBQUAD)];
//为新图像数据区分配内存
DWORD dwNewSize;
HGLOBAL hNewDibBits;
//新图像数据区大小
dwNewSize = nWidthBytes * nHeight;
//为新图像分配内存
hNewDibBits = ::GlobalAlloc( GMEM_MOVEABLE | GMEM_ZEROINIT, dwNewSize );
if( hNewDibBits == NULL )
{
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_ALLOCATION_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//新图像指针
pNewBits = (unsigned char *) ::GlobalLock( hNewDibBits );
if( pNewBits == NULL )
{
::GlobalFree( hNewDibBits );
m_pDibObject->m_nLastError = IMAGELIB_MEMORY_LOCK_ERROR;
::GlobalUnlock( m_pDibObject->GetDib() );
return( FALSE );
}
//用255(白色)填充新图像数据区
memset(pNewBits, (BYTE)255, nWidthBytes * nHeight );
for(y = 1; y < nHeight - 1; y++)
{
//指向源图像倒数第y行
pOldTemp = pOldBits;
pOldTemp += y * nWidthBytes;
//指向目标图像倒数第y行
pNewTemp = pNewBits;
pNewTemp += y * nWidthBytes;
for(x = 1; x < nWidth - 1; x++)
{
//取得当前指针处的像素值
pixel = *pOldTemp;
if(pixel == 0)
{
*pNewTemp = 0;
nw = *(pOldTemp + nWidthBytes - 1);
n = *(pOldTemp + nWidthBytes);
ne = *(pOldTemp + nWidthBytes + 1);
w = *(pOldTemp - 1);
e = *(pOldTemp + 1);
sw = *(pOldTemp - nWidthBytes - 1);
s = *(pOldTemp - nWidthBytes );
se = *(pOldTemp - nWidthBytes + 1);
//如果相邻的八个点都是黑点
if(nw + n + ne + w + e + sw + s + se == 0)
{
*pNewTemp = 255;
}
}
pOldTemp++;
pNewTemp++;
}
}
//用新图像数据填充原图像数据区
memcpy( pOldBits, pNewBits, nWidthBytes * nHeight );
::GlobalFree( hNewDibBits );
::GlobalUnlock( m_pDibObject->GetDib() );
return(TRUE);
}
////////////////////////////////////////////////////////////////////////
//BOOL Feeding1()
//----------------------------------------------------------------------
//基本功能:本函数对传入的CDibObject图像对象进行种子填充。
//----------------------------------------------------------------------
//参数说明:CDibObject *pDibObject 图像对象指针
//----------------------------------------------------------------------
//返 回:BOOL
// 成功时返回TRUE,失败时返回FALSE。
//----------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////
BOOL CAreaPro::Feeding1(CDibObject *pDibObject)
{
//图像指针为空,无法操作返回
if(m_pDibObject == NULL) return(FALSE);
//只支持8位图像
if(m_pDibObject->GetNumBits() != 8)
{
// 提示用户参数设置错误
AfxMessageBox("只支持8位图像,请重新载入!");
// 返回
return( FALSE );
}
//获取图像宽度和高度(以像素为单位)
int nWidth = m_pDibObject->GetWidth();
int nHeight = m_pDibObject->GetHeight();
//定义变量
unsigned char *pOldBuffer;
unsigned char *pOldBits;
unsigned char *pOldTemp;
BITMAPFILEHEADER *pOldBFH;
BITMAPINFOHEADER *pOldBIH;
RGBQUAD *pOldPalette;
int nWidthBytes, nNumColors;
//种子堆栈及指针
Seed *Seeds;
int StackPoint;
//当前像素位置
int iCurrentPixelx,iCurrentPixely;
//临时存放像素值
unsigned char pixel;
//原图像指针
pOldBuffer = (unsigned char *) m_pDibObject->GetDIBPointer(&nWidthBytes,
m_pDibObject->GetNumBits() );
if( pOldBuffer == NULL ) return( FALSE );
//原图像文件头指针
pOldBFH = (BITMAPFILEHEADER *) pOldBuffer;
//原图像信息头指针
pOldBIH = (BITMAPINFOHEADER *) &pOldBuffer[sizeof(BITMAPFILEHEADER)];
//原图像颜色数
nNumColors = m_pDibObject->GetNumColors();
//原图像调色板指针
pOldPalette = (RGBQUAD *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)];
//原图像数据指针
pOldBits = (unsigned char *) &pOldBuffer[sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)
+nNumColors*sizeof(RGBQUAD)];
//初始化种子
Seeds = new Seed[nWidthBytes * nHeight];
Seeds[1].Height = nHeight / 2;
Seeds[1].Width = nWidthBytes / 2;
StackPoint = 1;
while( StackPoint != 0)
{
//取出种子
iCurrentPixelx = Seeds[StackPoint].Width;
iCurrentPixely = Seeds[StackPoint].Height;
StackPoint--;
pOldTemp = pOldBits + nWidthBytes * iCurrentPixely + iCurrentPixelx;
//取得当前指针处的像素值
pixel = *pOldTemp;
//将当前点涂黑
*pOldTemp = 0;
//判断左面的点,如果为白,则压入堆栈
//注意防止越界
if(iCurrentPixelx > 0)
{
pOldTemp = pOldBits + nWidthBytes * iCurrentPixely + iCurrentPixelx - 1;
//取得当前指针处的像素值
pixel = *pOldTemp;
if (pixel == 255)
{
StackPoint++;
Seeds[StackPoint].Height = iCurrentPixely;
Seeds[StackPoint].Width = iCurrentPixelx - 1;
}
}
//判断上面的点,如果为白,则压入堆栈
//注意防止越界
if(iCurrentPixely < nHeight - 1)
{
pOldTemp = pOldBits + nWidthBytes * (iCurrentPixely + 1) + iCurrentPixelx;
//取得当前指针处的像素值
pixel = *pOldTemp;
if (pixel == 255)
{
StackPoint++;
Seeds[StackPoint].Height = iCurrentPixely + 1;
Seeds[StackPoint].Width = iCurrentPixelx;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -