Fork me on GitHub

图形学--边缘填充算法

算法描述:
边缘填充算法是先求出多边形的每条边与扫描线的交点,然后将交点右侧的所有像素颜色全部取为补色(或反色)。
按任意顺序处理完多边形的所有边后,就完成了多边形的填充任务。

边缘填充算法利用了图像处理中的求“补”或求“反”的概念,对于黑白图像,求补就是把RGB(255,255,255)(白色)的像素置为RGB(0,0,0)(黑色),反之亦然;对于彩色图像,求补就是将背景色置为填充色,反之亦然。求补的一条基本性质是一个像素求补两次就恢复为原色。如果多边形内部的像素被求补偶数次,保持原色,如果被求补奇数次,显示填充色。

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
/**
* points 是点数组
* point_num 是点的个数
* foregroundColor 是前景色
* backgroundColor 是背景色
* fence 是栅栏
* */
void edgeFillingAlgorithm(CPoint points[], int point_num,
COLORREF foregroundColor, COLORREF backgroundColor, int fence, CDC *pDC)
{
int yMin, yMax;//边的最小y和最大y
//x,y为当前点x、y坐标,reciprocalOfSlope为斜率分之一,1/k
double x, reciprocalOfSlope;
int y;

for (int i = 0; i < point_num; i++)
{
int j = (i + 1) % point_num;//j为相对于i的下一个点
if (points[i].y - points[j].y != 0)
{
reciprocalOfSlope = (points[i].x - points[j].x) * 1.0 / (points[i].y - points[j].y);

//TODO:以下处理,得到每条边的y的最大值和最小值
if (points[i].y < points[j].y)//斜率不为0时
{
yMin = points[i].y;
yMax = points[j].y;
x = points[i].x;
}
else
{
yMin = points[j].y;
yMax = points[i].y;
x = points[j].x;
}

for (y = yMin; y < yMax; y++)//沿每条扫描线处理
{
//对每条扫描线与边的交点的右侧像素循环,其中max_X是包围圈的右边界
if(x < fence)
{
for (int tempX = Round(x); tempX < fence; tempX++)
{
if (pDC->GetPixel(tempX, y) == foregroundColor)
{
pDC->SetPixelV(tempX, y, backgroundColor);
}
else
{
pDC->SetPixelV(tempX, y, foregroundColor);
}
}
}
else
{
for (int tempX = fence; tempX < x; tempX++)
{
if (pDC->GetPixel(tempX, y) == foregroundColor)
{
pDC->SetPixelV(tempX, y, backgroundColor);
}
else
{
pDC->SetPixelV(tempX, y, foregroundColor);
}
}
}
x = x + reciprocalOfSlope;
}
}
else //斜率为0时
{ }
}
}
扫描二维码,拯救贫困山区大学生!
-------------本文结束感谢您的阅读-------------