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);
}看不懂的,查资料!加油
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);
}看不懂的,查资料!加油
相关文章推荐
- 图像处理-MFC学习(7)——实现8*8数组的DCT、IDCT
- 【数字图像处理】 二.MFC单文档分割窗口显示图片
- 高性能图像处理服务器的实现(三)reactors in threads服务器模式中代码流程详解
- MFC多文档中opencv处理图像打开、保存
- Javascript图像处理思路及实现代码
- 图像处理之其他杂项(五)之水平集 LevelSet 代码实现 opencv c++ (转载)
- Java实现基于内容的数字图像处理代码
- java简单实现八叉树图像处理代码示例
- 数字图像处理基础(十一)---缩放、角度旋转和仿射变换及代码实现
- 【图像处理】OTSU二值化原理及代码实现
- 【图像处理】矩阵运算代码实现2-矩阵求逆
- Javascript图像处理思路及实现代码
- 图像处理中几个基本的处理方法c#代码实现
- 文档图像处理系统的设计与实现
- MFC多文档视图界面(MDI)搭建图像处理框架程序总结
- MFC下实现 灰度图像显示函数代码 C++
- 【图像处理】矩阵运算代码实现1
- ROS学习笔记(2):在ROS中使用OpenCV进行简单的图像处理---代码实现篇
- Detecting Oriented Text in Natural Images by Linking Segments:SegLink实现图像内文档识别的github代码复现实践笔记
- 创建基于opencv库的MFC多文档图像处理框架