案例10 扫描线种子填充算法
合集下载
相关主题
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
程序代码
PointTemp.x=xleft;PointTemp.y=PointTemp.y-2; //处理下一条扫描线 while(PointTemp.x<xright) { bSpanFill=FALSE; while(pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!=BoundaryClr && pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!=SeedClr) { bSpanFill=TRUE; PointTemp.x++; } if(bSpanFill) { if(PointTemp.x==xright && pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y))!=BoundaryClr && pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!=SeedClr) PopPoint=PointTemp; else PopPoint.x=PointTemp.x-1;PopPoint.y=PointTemp.y; Push(PopPoint); bSpanFill=FALSE; } while((pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))==BoundaryClr && PointTemp.x<xright) || (pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y)) ==SeedClr && PointTemp.x<xright)) PointTemp.x++; } }
计算机图形学实践教程(VisualC++版)(第2版)
案例10 扫描线种子填充算法
孔令德 太原工业学院计算机工程系 2017.1.10
知识点
扫描线种子填充算法原理。 判断种子像素位于空心汉字之内的方法。 堆栈操作函数。
案例描述
使用PhotoShop制作 “金梅浪漫空心体”汉字,如图10-
来自百度文库
总结
扫描线种子填充算法对于每一区间只保留其最右端像素 作为种子像素入栈,极大地减小了栈空间,有效地提高了填 充速度。
程序代码
CharFill()文字填充函数
while(pHead->pNext!=NULL)//如果栈不为空 { Pop(PopPoint); PointTemp=PopPoint; while(pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!= BoundaryClr&& pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!=SeedClr) { pDC->SetPixelV(Round(PointTemp.x),Round(PointTemp.y),SeedClr); PointTemp.x++; } xright=PointTemp.x-1;PointTemp.x=PopPoint.x-1; while(pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!= BoundaryClr&&pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!=SeedClr) { pDC->SetPixelV(Round(PointTemp.x),Round(PointTemp.y),SeedClr); PointTemp.x--; }
1所示,保存为BMP图片。请使用扫描线种子算法填充空心汉字。
图10-1空心汉字
效果图
图10-2 效果图
原理算法
(1)在屏幕客户区显示“书香”空心汉字位图。 (2)调用颜色对话框读取填充色,默认种子色为红色。 (3)鼠标选择种子的像素的坐标(x0,y0)位置,执行x=x0±1与 y=y0±1操作,判断x或y是否到达客户区边界。如果x或y到达客户区边 界,给出“种子不在图形之内”的警告信息,重新选择种子像素的位 置。 (4)将空心汉字内的种子像素入栈。 (5)如果栈不为空,将栈顶像素出栈,以y作为当前扫描线。 (6)填充并确定种子像素所在区间,从种子出发,沿当前扫描线向左 、右两个方向填充,直到边界,将区间最左端像素记为xleft,最右端像 素记为xright。 (7)在区间〔xleft,xright〕中检查与当前扫描线y相邻的上下两条扫描 线上的像素,若存在非边界像素或未填充像素,则把未填充区间的最 右端像素取作种子像素入栈,返回第(5)步。
程序代码
xleft=PointTemp.x+1;处理上一条扫描线 PointTemp.x=xleft;PointTemp.y=PointTemp.y+1; while(PointTemp.x<xright) { bSpanFill=FALSE; while(pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!= BoundaryClr&&pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))!=SeedClr) { bSpanFill=TRUE; PointTemp.x++; } if(bSpanFill) { if(PointTemp.x==xright&&pDC->GetPixel(Round(PointTemp.x) ,Round(PointTemp.y))!=BoundaryClr&& pDC->GetPixel(Round(PointTemp.x), Round(PointTemp.y))!=SeedClr) PopPoint=PointTemp; else PopPoint.x=PointTemp.x-1;PopPoint.y=PointTemp.y; Push(PopPoint); bSpanFill=FALSE; } while((pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y))==BoundaryClr && PointTemp.x<xright) || (pDC->GetPixel(Round(PointTemp.x),Round(PointTemp.y)) ==SeedClr && PointTemp.x<xright)) PointTemp.x++;