Android:如何做这个框架涂料?

标签 android android-canvas draw flood-fill

我有一些像下面这样的静态图片:

enter image description here

现在,我想要的是,当我触摸脸部或手部时,所选颜色应该填充到该皮肤部分。

结果见下图:

enter image description here

那么如何得到上面的结果呢?? 重做和撤消功能也应该在那里。

我已经尝试使用 FloodFill 颜色,但这样做我只能对特定部分进行颜色处理。因为 FloodFill 只填充颜色,直到出现相同的 pixwl 颜色。如果触摸位置像素颜色发生变化,它将不会在其上填充颜色。

所以 Usinf FloodFill 我得到了如下图所示的结果,如果我按下手,那么只有手的部分会填充颜色,而不是我想给另一只手和脸填充颜色。 enter image description here

所以请在这种情况下帮助我。

已编辑

经过一些回复,我得到了类似 this one 的解决方案.

但仍然存在内存问题。绘制颜色会消耗大量内存。那么,有人可以帮助我吗?

最佳答案

您可以让一个完整的图像以实际方式着色,当您用一种颜色填充某个区域时,它将替换所有由该颜色指定的要填充的区域。

外行术语:

  1. 用户将点击 OUTLINE 的手
  2. 该点击位置将与另一张具有完美颜色编码区域的图片进行核对。对于这种情况,我们称它为 MASK。所有皮肤区域都将具有相同的颜色。衬衫区域将是另一种颜色。
  3. 无论用户点击哪里,用户选择的颜色都会应用到 MASK 中具有相似颜色的每个像素,但不是直接在 MASK 上绘制,而是在 OUTLINE 的像素上绘制。

希望对您有所帮助。

如果你想要一个例子,请随时发表评论,然后我可以用它更新答案,但我认为你可以从这里得到它。

编辑:

基本上从像这样的简单图像开始。我们可以将其称为OUTLINE

Simple image

然后作为开发者,你必须做一些工作。在这里,您对 OUTLINE 进行颜色编码。我们称之为 MASK 的结果。为此,我们用您想要的相同颜色对区域进行颜色编码。这可以在油漆或其他任何东西上完成。我用 Photoshop 很酷哈哈 :D。

Mask

然后是让它在手机上运行的算法。在阅读代码之前,请查看此变量。

int ANTILAISING_TOLERANCE = 70; //Larger better coloring, reduced sensing

如果放大图像,特别注意边框的黑色区域,您实际上可以看到,有时计算机会稍微混合颜色。为了说明这种变化,我们使用这个容差值。

COLORINGANDROIDACTIVITY.JAVA

package mk.coloring;

import android.app.Activity;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.view.View.OnTouchListener;

public class ColoringAndroidActivity extends Activity implements OnTouchListener{
    /** Called when the activity is first created. */
@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.main);
    findViewById(R.id.imageView1).setOnTouchListener(this);
}

int ANTILAISING_TOLERANCE = 70;
public boolean onTouch(View arg0, MotionEvent arg1) {
    Bitmap mask = BitmapFactory.decodeResource(getResources(), R.drawable.mask);
    int selectedColor = mask.getPixel((int)arg1.getX(),(int)arg1.getY());           
    int sG = (selectedColor & 0x0000FF00) >> 8;
    int sR = (selectedColor & 0x00FF0000) >> 16;
    int sB = (selectedColor & 0x000000FF);

    Bitmap original = BitmapFactory.decodeResource(getResources(), R.drawable.empty);       
    Bitmap colored = Bitmap.createBitmap(mask.getWidth(), mask.getHeight(), Config.ARGB_8888);
    Canvas cv = new Canvas(colored);
    cv.drawBitmap(original, 0,0, null);

    for(int x = 0; x<mask.getWidth();x++){
        for(int y = 0; y<mask.getHeight();y++){
            int g = (mask.getPixel(x,y) & 0x0000FF00) >> 8;
            int r = (mask.getPixel(x,y) & 0x00FF0000) >> 16;
            int b = (mask.getPixel(x,y) & 0x000000FF);
            if(Math.abs(sR - r) < ANTILAISING_TOLERANCE && Math.abs(sG - g) < ANTILAISING_TOLERANCE && Math.abs(sB - b) < ANTILAISING_TOLERANCE)
                colored.setPixel(x, y, (colored.getPixel(x, y) & 0xFF000000) | 0x00458414);
        }
    }
    ((ImageView)findViewById(R.id.imageView1)).setImageBitmap(colored);

    return true;
}

这段代码没有为用户提供很多颜色选择。相反,如果用户触摸某个区域,它将查看 MASK 并相应地绘制 OUTLINE。但是,您可以制作出非常有趣和互动的内容。

结果

当我抚摸那个男人的头发时,不仅头发染上了颜色,而且他的衬衫和手也染上了同样的颜色。将其与MASK 进行比较,以更好地了解发生了什么。

Result

这只是一个基本的想法。我已经创建了多个位图,但实际上并不需要这样做。我曾将它用于测试目的并占用了不必要的内存。而且您不需要在每次点击时重新创建蒙版等。

希望对你有帮助:D

祝你好运

关于Android:如何做这个框架涂料?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9748206/

相关文章:

android - 如何在 AsyncTask 中执行函数?

android - 在 Canvas 上绘制 PNG 图像 : performance issue

android - 延迟在 Canvas 上绘制 - "make onDraw() slow down"

android - 为什么我对 Canvas.drawText() 的调用不起作用

javascript - 如何在 Canvas 上制作弹跳球的动画

java - 为什么我的屏幕上什么也没有绘制?

Android viewModel savedStateHandle

android - 如何在聊天应用程序中存储上次查看的消息

android - <Image> url 没有显示为 android React Native

android - 在 Android 上不缩放绘制位图