您的位置:首页 > 编程语言

MFC单文档图像处理代码--句柄图像实现

2017-08-18 14:21 633 查看
1.句柄图像灰度化+二值化

void Convert256toGray(HDIB hDIB,int a,int b,int c,int d)
{
LPSTR lpDIB;

// 由DIB句柄得到DIB指针并锁定DIB
lpDIB = (LPSTR) ::GlobalLock((HGLOBAL)hDIB);

// 指向DIB象素数据区的指针
LPSTR lpDIBBits;

// 指向DIB象素的指针
BYTE * lpSrc;

// 图像宽度
LONG lWidth;
// 图像高度
LONG lHeight;

// 图像每行的字节数
LONG lLineBytes;

// 指向BITMAPINFO结构的指针(Win3.0)
LPBITMAPINFO lpbmi;

// 指向BITMAPCOREINFO结构的指针
LPBITMAPCOREINFO lpbmc;

// 获取指向BITMAPINFO结构的指针(Win3.0)
lpbmi = (LPBITMAPINFO)lpDIB;

// 获取指向BITMAPCOREINFO结构的指针
lpbmc = (LPBITMAPCOREINFO)lpDIB;

// 灰度映射表
BYTE bMap[256];

// 计算灰度映射表(保存各个颜色的灰度值),并更新DIB调色板
int i,j;
for (i = a; i < 256; i ++)
{
// 计算该颜色对应的灰度值
bMap[i] = (BYTE)(0.299 * lpbmi->bmiColors[i].rgbRed +

0.587 * lpbmi->bmiColors[i].rgbGreen +

0.114 * lpbmi->bmiColors[i].rgbBlue + 0.5);
// 更新DIB调色板红色分量
lpbmi->bmiColors[i].rgbRed = i;

// 更新DIB调色板绿色分量
lpbmi->bmiColors[i].rgbGreen = i;

// 更新DIB调色板蓝色分量
lpbmi->bmiColors[i].rgbBlue = i;

// 更新DIB调色板保留位
lpbmi->bmiColors[i].rgbReserved = 0;

}
// 找到DIB图像象素起始位置
lpDIBBits = ::FindDIBBits(lpDIB);

// 获取图像宽度
lWidth = ::DIBWidth(lpDIB);

// 获取图像高度
lHeight = ::DIBHeight(lpDIB);

// 计算图像每行的字节数
lLineBytes = WIDTHBYTES(lWidth * 8);

// 更换每个象素的颜色索引(即按照灰度映射表换成灰度值)

//逐行扫描
for(i = 0; i < lWidth; i++)
{

//逐列扫描
for(j = 0; j < lHight; j++)
{
// 指向DIB第i行,第j个象素的指针
lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (lHeight - 1 - i) + j;

// 变换
*lpSrc = bMap[*lpSrc];
}

//最简单二值化:找灰度值,大于127的全部变成255,小于127的全部变成0

for(i=0;i<lWidth;i++){
for (j=0;j<lHight;j++)
{
if (bMap[i]<127)
{
bMap[i]=0;
}else{
bMap[i]=255;
}
}
*lpSrc = bMap[*lpSrc];
}
}

//解除锁定
::GlobalUnlock ((HGLOBAL)hDIB);
}
2.句柄图像旋转
#define PI 3.14159

#define RADIAN(angle) ((angle)*PI/180.0)
HGLOBAL WINAPI RotateDIB(LPSTR lpDIB, int iRotateAngle)
{
LONG lWidth;
LONG lHeight;
LONG lNewWidth;
LONG lNewHeight;
LONG lLineBytes;
LONG lNewLineBytes;
LPSTR lpDIBBits;
LPSTR lpSrc;
HDIB hDIB;
LPSTR lpDst;
LPSTR lpNewDIB;
LPSTR lpNewDIBBits;
LPBITMAPINFOHEADER lpbmi;
LPBITMAPCOREHEADER lpbmc;
LONG i;
LONG j;
LONG i0;
LONG j0;
float fRotateAngle;
float fSina, fCosa;
float fSrcX1,fSrcY1,fSrcX2,fSrcY2,fSrcX3,fSrcY3,fSrcX4,fSrcY4;
float fDstX1,fDstY1,fDstX2,fDstY2,fDstX3,fDstY3,fDstX4,fDstY4;
float f1,f2;
lpDIBBits = ::FindDIBBits(lpDIB);
lWidth = ::DIBWidth(lpDIB);
lLineBytes = WIDTHBYTES(lWidth * 8);
lHeight = ::DIBHeight(lpDIB);
fRotateAngle = (float) RADIAN(iRotateAngle);
fSina = (float) sin((double)fRotateAngle);
fCosa = (float) cos((double)fRotateAngle);
fSrcX1 = (float) (- (lWidth - 1) / 2);
fSrcY1 = (float) ( (lHeight - 1) / 2);
fSrcX2 = (float) ( (lWidth - 1) / 2);
fSrcY2 = (float) ( (lHeight - 1) / 2);
fSrcX3 = (float) (- (lWidth - 1) / 2);
fSrcY3 = (float) (- (lHeight - 1) / 2);
fSrcX4 = (float) ( (lWidth - 1) / 2);
fSrcY4 = (float) (- (lHeight - 1) / 2);
fDstX1 = fCosa * fSrcX1 + fSina * fSrcY1;
fDstY1 = -fSina * fSrcX1 + fCosa * fSrcY1;
fDstX2 = fCosa * fSrcX2 + fSina * fSrcY2;
fDstY2 = -fSina * fSrcX2 + fCosa * fSrcY2;
fDstX3 = fCosa * fSrcX3 + fSina * fSrcY3;
fDstY3 = -fSina * fSrcX3 + fCosa * fSrcY3;
fDstX4 = fCosa * fSrcX4 + fSina * fSrcY4;
fDstY4 = -fSina * fSrcX4 + fCosa * fSrcY4;
lNewWidth = (LONG) ( max( fabs(fDstX4 - fDstX1), fabs(fDstX3 - fDstX2) ) + 0.5);
lNewLineBytes = WIDTHBYTES(lNewWidth * 8);
lNewHeight = (LONG) ( max( fabs(fDstY4 - fDstY1), fabs(fDstY3 - fDstY2) ) + 0.5);
f1 = (float) (-0.5 * (lNewWidth - 1) * fCosa - 0.5 * (lNewHeight - 1) * fSina
+ 0.5 * (lWidth - 1));
f2 = (float) ( 0.5 * (lNewWidth - 1) * fSina - 0.5 * (lNewHeight - 1) * fCosa
+ 0.5 * (lHeight - 1));
hDIB = (HDIB) ::GlobalAlloc(GHND, lNewLineBytes * lNewHeight + *(LPDWORD)lpDIB + ::PaletteSize(lpDIB));
if (hDIB == NULL)
{
return NULL;
}
lpNewDIB = (char * )::GlobalLock((HGLOBAL) hDIB);
memcpy(lpNewDIB, lpDIB, *(LPDWORD)lpDIB + ::PaletteSize(lpDIB));
lpNewDIBBits = ::FindDIBBits(lpNewDIB);
lpbmi = (LPBITMAPINFOHEADER)lpNewDIB;
lpbmc = (LPBITMAPCOREHEADER)lpNewDIB;
if (IS_WIN30_DIB(lpNewDIB))
{
lpbmi->biWidth = lNewWidth;
lpbmi->biHeight = lNewHeight;
}
else
{
lpbmc->bcWidth = (unsigned short) lNewWidth;
lpbmc->bcHeight = (unsigned short) lNewHeight;
}
for(i = 0; i < lNewHeight; i++)
{
for(j = 0; j < lNewWidth; j++)
{
lpDst = (char *)lpNewDIBBits + lNewLineBytes * (lNewHeight - 1 - i) + j;
i0 = (LONG) (-((float) j) * fSina + ((float) i) * fCosa + f2 + 0.5);
j0 = (LONG) ( ((float) j) * fCosa + ((float) i) * fSina + f1 + 0.5);
if( (j0 >= 0) && (j0 < lWidth) && (i0 >= 0) && (i0 < lHeight))
{
lpSrc = (char *)lpDIBBits + lLineBytes * (lHeight - 1 - i0) + j0;
*lpDst = *lpSrc;
}
else
{
* ((unsigned char*)lpDst) = 255;
}

}

}
return hDIB;
}3.ROI区域实现
////////roi区域
void CMyDIPView::OnLButtonDown(UINT nFlags, CPoint point)
{
TopX = point.x;
TopY = point.y;

flag_LMoseDown = true;
LeftTopPoint = point;
RightBottomPoint = point;
//设置光标
::SetCursor(Cross);
// TODO: 在此添加消息处理程序代码和/或调用默认值

CScrollView::OnLButtonDown(nFlags, point);
}

void CMyDIPView::OnMouseMove(UINT nFlags, CPoint point)
{
if(flag_LMoseDown)
{
CClientDC dc(this);

dc.SetROP2(R2_NOT);
dc.SelectStockObject(NULL_BRUSH);
::SetCursor(Cross);

RightBottomPoint = point;
}
// TODO: 在此添加消息处理程序代码和/或调用默认值

CScrollView::OnMouseMove(nFlags, point);
}

void CMyDIPView::OnLButtonUp(UINT nFlags, CPoint point)
{
//记录松开点的坐标信息
BottomX = point.x;
BottomY = point.y;

width = BottomX-TopX;
height = BottomY-TopY;
//判断所选区域是否合格
if(height < 0||width < 0)
{
MessageBox(TEXT("请从左上角开始选取"));
return ;
}
if(height > width)
{
MessageBox(TEXT("请选取一个横向矩形"));
return ;
}

flag_LMoseDown = false;
CClientDC dc(this);
dc.SetROP2(R2_NOT);
dc.SelectStockObject(NULL_BRUSH);
::ClipCursor(NULL);
RightBottomPoint = point;
//画出所选矩形区域
dc.Rectangle(CRect(LeftTopPoint,RightBottomPoint));
//创建CRect类的对象保存ROI区域长宽,起始终止点的信息
ret = new CRect(LeftTopPoint,RightBottomPoint);
flagBinROI = true;

CScrollView::OnLButtonUp(nFlags, point);
}看不懂的,查资料!加油
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: