VC编程实现位图拷贝、切除白边
VC编程实现位图图像二值化、反相介绍了VC对位图图像二值化、反相处理,本文继续介绍位图处理类CImageUtility的其它成员方法,限于篇幅,本文着重介绍VC编程实现切除二值图的空白边、位图图像拷贝的两个成员方法。
1. 切除二值图的空白边
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
|
//切除二值图的空白边
void
CImageUtility::ImageCutBlankProcess(){
// 目前只处理24位以上的位图
if
(nPixBytes <3)
return
;
//有效区域
RECT vRect;
vRect.top=0;
vRect.left=0;
vRect.right=bmSrcInfo.bmWidth;
vRect.bottom=bmSrcInfo.bmHeight;
//循环控制开关
bool
bStop;
double
limenGray=255;
// 1.求有效区域的Top值
bStop=
false
;
for
(
long
nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)
{
for
(
long
nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++)
{
//将RGB分量保存成为对应的灰度值
for
(
int
np2=0; np2<nPixBytes; np2++)
{
//判断三个颜色分量是否为
if
(pBmBits[bmSrcInfo.bmWidthBytes*nHeight+nWidth*nPixBytes + np2]<limenGray){
vRect.top=nHeight;
bStop=
true
;
break
;
}
}
if
(bStop)
break
;
}
if
(bStop)
break
;
}
// 2.求有效区域的Left值
bStop=
false
;
for
(
long
nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++)
{
for
(
long
nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)
{
//将RGB分量保存成为对应的灰度值
for
(
int
np2=0; np2<nPixBytes; np2++)
{
//判断三个颜色分量是否为
if
(pBmBits[bmSrcInfo.bmWidthBytes*nHeight+nWidth*nPixBytes + np2]<limenGray){
vRect.left=nWidth;
bStop=
true
;
break
;
}
}
if
(bStop)
break
;
}
if
(bStop)
break
;
}
// 3.求有效区域的Bottom值
bStop=
false
;
for
(
long
nHeight=bmSrcInfo.bmHeight-1; nHeight>=0; nHeight--)
{
for
(
long
nWidth=0; nWidth<bmSrcInfo.bmWidth; nWidth++)
{
//将RGB分量保存成为对应的灰度值
for
(
int
np2=0; np2<nPixBytes; np2++)
{
//判断三个颜色分量是否为
if
(pBmBits[bmSrcInfo.bmWidthBytes*nHeight+nWidth*nPixBytes + np2]<limenGray){
vRect.bottom=nHeight+1;
bStop=
true
;
break
;
}
}
if
(bStop)
break
;
}
if
(bStop)
break
;
}
// 4.求有效区域的Right值
bStop=
false
;
for
(
long
nWidth=bmSrcInfo.bmWidth-1; nWidth>=0; nWidth--)
{
for
(
long
nHeight=0; nHeight<bmSrcInfo.bmHeight; nHeight++)
{
//将RGB分量保存成为对应的灰度值
for
(
int
np2=0; np2<nPixBytes; np2++)
{
//判断三个颜色分量是否为
if
(pBmBits[bmSrcInfo.bmWidthBytes*nHeight+nWidth*nPixBytes + np2]<limenGray){
vRect.right=nWidth+1;
bStop=
true
;
break
;
}
}
if
(bStop)
break
;
}
if
(bStop)
break
;
}
//拷贝满足要求的位图区域
HBITMAP
cutBitmap=CopyBitmap((
HBITMAP
)(*bmpSrc),&vRect);
::DeleteObject((
HBITMAP
)bmpSrc);
this
->loadHBitmap(cutBitmap);
}
|
首先对二值图像进行行扫描,获取首行不是空白行的行号,末行不是空白行的行号,然后对二值图像进行列扫描,获取首列不是空白列的列号,末列不是空白列的列号,将获取的区域作为形参,调用位图拷贝函数:
1
|
HBITMAP
cutBitmap=CopyBitmap((
HBITMAP
)(*bmpSrc),&vRect);
|
将指定区域内的像素信息拷贝出来形成一个新的二值图图像。
2. 位图图像拷贝
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
|
// 位图拷贝的实现
// pRect:定义拷贝位图区域的指针
HBITMAP
CImageUtility::CopyBitmap(
HBITMAP
hSourcehBitmap,RECT* pRect)
{
// 定义设备描述表
CDC sourcedc;
CDC destdc;
sourcedc.CreateCompatibleDC(NULL);
destdc.CreateCompatibleDC(NULL);
//the bitmap information.
BITMAP bm = {0};
//get the bitmap information.
::GetObject(hSourcehBitmap,
sizeof
(bm), &bm);
// 根据用户是否定义了拷贝区域执行相应的操作
int
imgWidth=bm.bmWidth;
//图像的宽度
int
imgHeight=bm.bmHeight;
//图像的高度
int
srcX=0;
//源图像X起点
int
srcY=0;
//源图像Y起点
// 根据用户是否定义了拷贝区域执行相应的操作
if
(pRect!=NULL){
imgWidth=bm.bmWidth<
abs
(pRect->right-pRect->left)?bm.bmWidth:
abs
(pRect->right-pRect->left);
imgHeight=bm.bmHeight<
abs
(pRect->bottom-pRect->top)?bm.bmHeight:
abs
(pRect->bottom-pRect->top);
srcX=pRect->left;
srcY=pRect->top;
}
// create a bitmap to hold the result
HBITMAP
hbmresult = ::CreateCompatibleBitmap(CClientDC(NULL), imgWidth, imgHeight);
HBITMAP
hbmoldsource = (
HBITMAP
)::SelectObject(sourcedc.m_hDC, hSourcehBitmap);
HBITMAP
hbmolddest = (
HBITMAP
)::SelectObject(destdc.m_hDC, hbmresult);
destdc.BitBlt(0,0,imgWidth, imgHeight, &sourcedc, srcX, srcY, SRCCOPY);
// restore dcs
::SelectObject(sourcedc.m_hDC, hbmoldsource);
::SelectObject(destdc.m_hDC, hbmolddest);
::DeleteObject(sourcedc.m_hDC);
::DeleteObject(destdc.m_hDC);
return
hbmresult;
}
|
到此,便完成了切除位图空白边,拷贝位图图像的成员函数