Android不规则封闭区域填充色彩的实例代码

一、概述

在上一篇的叙述中,我们通过图层的方式完成了图片颜色的填充(详情请戳:Android不规则图像填充颜色小游戏),不过在着色游戏中更多的还是基于边界的图像的填充。本篇博客将详细描述。

图像的填充有2种经典算法。

一种是种子填充法。

种子填充法理论上能够填充任意区域和图形,但是这种算法存在大量的反复入栈和大规模的递归,降低了填充效率。

另一种是扫描线填充法。

注意:实际上图像填充的算法还是很多的,有兴趣可以去Google学术上去搜一搜。

ok,下面先看看今天的效果图:

img

ok,可以看到这样的颜色填充比上一篇的基于层的在素材的准备上要easy 很多~~~

二、原理分析

首先我们简述下原理,我们在点击的时候拿到点击点的”颜色”,然后按照我们选择的算法进行填色即可。

算法1:种子填充法,四联通/八联通

算法简介:假设要将某个区域填充成红色。

从用户点击点的像素开始,上下左右(八联通还有左上,左下,右上,右下)去判断颜色,如果四个方向上的颜色与当前点击点的像素一致,则改变颜色至目标色。然后继续上述这个过程。

ok,可以看到这是一个递归的过程,1个点到4个,4个到16个不断的去延伸。如果按照这种算法,你会写出类似这样的代码:

/**
 * @param pixels 像素数组
 * @param w 宽度
 * @param h 高度
 * @param pixel 当前点的颜色
 * @param newColor 填充色
 * @param i 横坐标
 * @param j 纵坐标
 */
 private void fillColor01(int[] pixels, int w, int h, int pixel, int newColor, int i, int j)
 {
   
 int index = j * w + i;
 if (pixels[index] != pixel || i  = w || i < 0 || j < 0 || j  = h)
 return;
 pixels[index] = newColor;
 //上
 fillColor01(pixels, w, h, pixel, newColor, i, j - 1);
 //右
 fillColor01(pixels, w, h, pixel, newColor, i + 1, j);
 //下
 fillColor01(pixels, w, h, pixel, newColor, i, j + 1);
 //左
 fillColor01(pixels, w, h, pixel, newColor, i - 1, j);
 }

代码很简单,但是如果你去运行,会发生StackOverflowException异常,这个异常主要是因为大量的递归造成的。虽然简单,但是在移动设备上使用该方法不行。

于是,我就想,这个方法不是递归深度过多么,那么我可以使用一个Stack去存像素点,减少递归的深度和次数,于是我把代码改成如下的方式:

/**
 * @param pixels 像素数组
 * @param w 宽度
 * @param h 高度
 * @param pixel 当前点的颜色
 * @param newColor 填充色
 * @param i 横坐标
 * @param j 纵坐标
 */
 private void fillColor(int[] pixels, int w, int h, int pixel, int newColor, int i, int j)
 {
   
 mStacks.push(new Point(i, j));

 while (!mStacks.isEmpty())
 {
   
 Point seed = mStacks.pop();
 Log.e("TAG", "seed = " + seed.x + " , seed = " + seed.y);

 int index = seed.y * w + seed.x;

 pixels[index] = newColor;
 if (seed.y   0)
 {
   
 int top = index - w;
 if (pixels[top] == pixel)
 {
   

 mStacks.push(new Point(seed.x, seed.y - 1));
 }
 }

 if (seed.y < h - 1)
 {
   
 int bottom = index + w;
 if (pixels[bottom] == pixel)
 {
   
 mStacks.push(new Point(seed.x, seed.y + 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值