使用泛洪填充算法在Android中填充图案而不是颜色

4

我正在开发一个涂色应用程序,使用以下代码可以将图像的白色填充为不同的颜色。
这是Java类:

import java.util.LinkedList;
import java.util.Queue;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.BitmapFactory.Options;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Path;
import android.graphics.Point;
import android.os.AsyncTask;
import android.os.Bundle;
import android.view.MotionEvent;
import android.view.View;
import android.widget.Button;
import android.widget.ImageView;
import android.widget.RelativeLayout;

public class Main extends Activity {

private RelativeLayout dashBoard;
private MyView myView;
public ImageView image;

Button b_red, b_blue, b_green, b_orange, b_clear;

@Override
protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    myView = new MyView(this);
    setContentView(R.layout.activity_main);
    findViewById(R.id.dashBoard);

    b_red = (Button) findViewById(R.id.b_red);
    b_blue = (Button) findViewById(R.id.b_blue);
    b_green = (Button) findViewById(R.id.b_green);
    b_orange = (Button) findViewById(R.id.b_orange);

    b_red.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            myView.changePaintColor(0xFFFF0000);
        }
    });

    b_blue.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            myView.changePaintColor(0xFF0000FF);
        }
    });

    b_green.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            myView.changePaintColor(0xFF00FF00);
        }
    });

    b_orange.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            myView.changePaintColor(0xFFFF9900);
        }
    });

    dashBoard = (RelativeLayout) findViewById(R.id.dashBoard);
    dashBoard.addView(myView);

}

public class MyView extends View {

    private Paint paint;
    private Path path;
    public Bitmap mBitmap;
    public ProgressDialog pd;
    final Point p1 = new Point();
    public Canvas canvas;

    //Bitmap mutableBitmap ;
    public MyView(Context context) {

        super(context);

        this.paint = new Paint();
        this.paint.setAntiAlias(true);
        pd = new ProgressDialog(context);
        this.paint.setStyle(Paint.Style.STROKE);
        paint.setStrokeJoin(Paint.Join.ROUND);
        paint.setStrokeWidth(5f);
        mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.forme).copy(Bitmap.Config.ARGB_8888, true);
        this.path = new Path();
    }

    @Override
    protected void onDraw(Canvas canvas) {
        this.canvas = canvas;
        this.paint.setColor(Color.RED);

        canvas.drawBitmap(mBitmap, 0, 0, paint);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {

        float x = event.getX();
        float y = event.getY();

        switch (event.getAction()) {

            case MotionEvent.ACTION_DOWN:

                p1.x = (int) x;
                p1.y = (int) y;
                final int sourceColor = mBitmap.getPixel((int) x, (int) y);
                final int targetColor = paint.getColor();
                new TheTask(mBitmap, p1, sourceColor, targetColor).execute();
                invalidate();
        }
        return true;
    }

    public void clear() {
        path.reset();
        invalidate();
    }

    public int getCurrentPaintColor() {
        return paint.getColor();
    }

    public void changePaintColor(int color){
        this.paint.setColor(color);
    }

    class TheTask extends AsyncTask<Void, Integer, Void> {

        Bitmap bmp;
        Point pt;
        int replacementColor, targetColor;

        public TheTask(Bitmap bm, Point p, int sc, int tc) {
            this.bmp = bm;
            this.pt = p;
            this.replacementColor = tc;
            this.targetColor = sc;
            pd.setMessage("Filling....");
            pd.show();
        }

        @Override
        protected void onPreExecute() {
            pd.show();

        }

        @Override
        protected void onProgressUpdate(Integer... values) {

        }

        @Override
        protected Void doInBackground(Void... params) {
            FloodFill f = new FloodFill();
            f.floodFill(bmp, pt, targetColor, replacementColor);
            return null;
        }

        @Override
        protected void onPostExecute(Void result) {
            pd.dismiss();
            invalidate();
        }
    }
}

// flood fill
public class FloodFill {

    public void floodFill(Bitmap image, Point node, int targetColor, int replacementColor) {

        int width = image.getWidth();
        int height = image.getHeight();
        int target = targetColor;
        int replacement = replacementColor;

        if (target != replacement) {
            Queue<Point> queue = new LinkedList<Point>();
            do {

                int x = node.x;
                int y = node.y;
                while (x > 0 && image.getPixel(x - 1, y) == target) {
                    x--;
                }

                boolean spanUp = false;
                boolean spanDown = false;
                while (x < width && image.getPixel(x, y) == target) {
                    image.setPixel(x, y, replacement);
                    if (!spanUp && y > 0 && image.getPixel(x, y - 1) == target) {
                        queue.add(new Point(x, y - 1));
                        spanUp = true;
                    } else if (spanUp && y > 0 && image.getPixel(x, y - 1) != target) {
                        spanUp = false;
                    }
                    if (!spanDown && y < height - 1 && image.getPixel(x, y + 1) == target) {
                        queue.add(new Point(x, y + 1));
                        spanDown = true;
                    } else if (spanDown && y < (height - 1) && image.getPixel(x, y + 1) != target) {
                        spanDown = false;
                    }
                    x++;
                }

            } while ((node = queue.poll()) != null);
        }
    }
}
}

您好,如您所见,我在图像中使用了填充洪水算法来给白色区域着色。
以下是要用来填充颜色的图像:
图像

现在问题是,我如何用下面的纹理(或其他任何纹理)来填充白色空间区域,而不是颜色?
纹理图像

由于我是新手,希望能得到任何帮助。谢谢。
1个回答

3

经过一些小技巧后,我成功使用泛洪算法在闭合区域中填充了图案。以下是我所做的:
1.引入一个新的具有图案的位图,如下所示。

bitmapPattern = BitmapFactory.decodeResource(getResources(),R.drawable.pattern1).copy(Bitmap.Config.ARGB_8888, true);
  1. And passed this bitmapPattern to the Flood Fill Algorithm as follows.

    FloodFillPattern f = new FloodFillPattern();  
    f.floodFillPattern(bmp, pt, targetColor, replacementColor, pattern);
    
  2. Note you have to scale this bitmap equal to the size of your image in which you will fill this pattern.

  3. Then simply replace the pixels of your original image with the pixels of the pattern bitmap in the flood fill algorithm. As Follows:

    image.setPixel(x, y, pattern.getPixel(x,y));
    

模式(pattern)是您传递的patternBitmap(模式位图)
希望能对某人有所帮助 :)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接