开发者社区> 最美的回忆> 正文
阿里云
为了无法计算的价值
打开APP
阿里云APP内打开

漫水填充及Photoshop中魔术棒选择工具的实现

简介:
+关注继续查看

今天写程序中有一个地方用到了漫水填充(FloodFill)。所谓漫水填充,简单来说,如下图中左图,白布上有一块红色的斑点,在这个红色的斑点上点一下,就自动选中了和该点相连的红色的区域,接着将该区域替换成指定的颜色,如下图中右图所示。

image

GDI中有一个函数 ExtFloodFill ,可以用于漫水填充。函数原型是:

BOOL ExtFloodFill(HDC hdc,int nXStart,int nYStart,COLORREF crColor,UINT fuFillType)

在C#中使用这个函数并不好用,这里有一个例子 http://www.codeproject.com/Feature/WickedCode.aspx?msg=2364985 。照猫画虎的写了一遍,结果返回的结果是false——填充失败。

对win32这些东西看着就烦,也没心思去看到底哪里出错了,干脆自己写一个 FloodFill 算法得了。

算法很简单:

(1)将最初的点作为种子点压入栈中;

(2)弹出一个种子点,把它涂成目标颜色;

(3)对于种子点来说,和它相邻的有4个像素,判断这4个像素中的颜色是否是背景色,如果是,则作为新的种子点入栈;

image

(4)循环至栈空。

实现起来也很简单,一共只需要22行代码,比用DllImport去调用ExtFloodFill代码量还少:

void FloodFill(ImageRgb24 img, Point location, Rgb24 backColor, Rgb24 fillColor) 

    int width = img.Width; 
    int height = img.Height; 
    if (location.X < 0 || location.X >= width || location.Y < 0 || location.Y >= height) return;

    if (backColor == fillColor) return; 
    if (img[location.Y, location.X] != backColor) return;

    Stack<Point> points = new Stack<Point>(); 
    points.Push(location);

    int ww = width -1; 
    int hh = height -1;

    while (points.Count > 0) 
    { 
        Point p = points.Pop(); 
        img[p.Y, p.X] = fillColor; 
        if (p.X > 0 && img[p.Y, p.X - 1] == backColor) 
        { 
            img[p.Y, p.X - 1] = fillColor; 
            points.Push(new Point(p.X - 1, p.Y)); 
        }

        if (p.X < ww && img[p.Y, p.X + 1] == backColor) 
        { 
            img[p.Y, p.X + 1] = fillColor; 
            points.Push(new Point(p.X + 1, p.Y)); 
        }

        if (p.Y > 0 && img[p.Y - 1, p.X] == backColor) 
        { 
            img[p.Y - 1, p.X] = fillColor; 
            points.Push(new Point(p.X, p.Y - 1)); 
        }

        if (p.Y < hh && img[p.Y + 1, p.X] == backColor) 
        { 
            img[p.Y + 1, p.X] = fillColor; 
            points.Push(new Point(p.X, p.Y + 1)); 
        } 
    } 
}

有这个算法为基础,类似photoshop的魔术棒选择工具就很容易实现了。漫水填充(FloodFill)是查找和种子点联通的颜色相同的点,魔术棒选择工具则是查找和种子点联通的颜色相近的点,将和初始种子点颜色相近的点压进栈作为新种子。

在photoshop cs5中新引进了快速选择工具,这个工具看起来很神奇,它背后的算法也研究了有些年了,就是抠图技术,有兴趣的可以去研究,这里有一篇很好的综述文章:《Image and Video Matting: A Survey》。

本文转自xiaotie博客园博客,原文链接http://www.cnblogs.com/xiaotie/archive/2010/09/08/1821100.html如需转载请自行联系原作者


xiaotie 集异璧实验室(GEBLAB)

版权声明:本文内容由阿里云实名注册用户自发贡献,版权归原作者所有,阿里云开发者社区不拥有其著作权,亦不承担相应法律责任。具体规则请查看《阿里云开发者社区用户服务协议》和《阿里云开发者社区知识产权保护指引》。如果您发现本社区中有涉嫌抄袭的内容,填写侵权投诉表单进行举报,一经查实,本社区将立刻删除涉嫌侵权内容。

相关文章
我绘制文章插图的三个神级工具
今天来给大家介绍三个我在制作文章插图时经常使用的堪称神级的工具,每一个工具都可以绘制非常精美图片,对于经常输出文章的朋友来说,绝对不容错过~
0 0
Photoshop隐藏的彩蛋
第一次接触彩蛋是微软的Excel里面的赛车游戏, 当时作者还上小学, 游戏资源很少, 微机室又不让随便装游戏, 于是小伙伴们经常打开excel找赛车游戏玩, 后来特地查了一下office各个版本的隐藏彩蛋, 真的是比office套件的软件数量都多,...
1012 0
使用photoshop制作一寸相并设置大小
    使用photoshop制作一寸相步骤如下: 图1 图2     这个尺寸已经附合一寸相的大小尺寸了,但是有其目前还有22k大小,在某些地方是不附合要求的。
480 0
另辟蹊径——使用 Photoshop 制作网页线框图
  这篇文章向大家介绍一套免费的 Photoshop 线框图套件,这个线框图套件中包括通知、图片和视频,表单字段,标题,段落,项目符号列表,导航,广告横幅和普通网站的元素,如:搜索框,电子邮件注册表单等等。
940 0
Photoshop制作自己的篆刻印章图案
  篆刻是我国独有的一门艺术,历史久远。古代的书画家大都有自己一些独特风格的印章来标记自己的作品,经过两千多年前人的积累和发展,篆刻逐渐成为一门大家喜欢的艺术,一枚好的印章不但是给自己的作品作标记,同时对平衡作品的画面构图也是具有非常大的作用。
830 0
30个非常棒的Photoshop文字特效制作教程
  相信对设计感兴趣的朋友都对使用Photoshop制作3D文字效果有一定的了解,以文字为主体的设计一样可以很美。今天,这篇文章向大家推荐30个非常棒的Photoshop文字特效教程,跟着教程学习如果制作出漂亮的文字效果。
899 0
7款调色板工具推荐
在web设计过程中,确定好一个调色板是首要事情。今天我们来看看推荐如下7款调色板工具,便于你在设计项目中利用。 Kuler 基于web的AIR应用。 Color Scheme Designer 同样也是基于web的色彩应用。
1448 0
文章
问答
文章排行榜
最热
最新
相关电子书
更多
《如何制作一个水平仪》
立即下载
骨骼动画实践
立即下载
低代码开发师(初级)实战教程
立即下载