java–Android泛洪填充算法

java–Android泛洪填充算法,第1张

概述有谁知道一个迭代和有效的洪水填充算法?或者有没有办法实现递归填充算法没有堆栈溢出错误?试过一个@Floodfillusingastack但我找不到一种方法来处理白色和黑色的图像.解决方法:有人将J.Dunlap’sQueue-LinearFloodFill算法移植到androidhere.我已经尝试了它并且速度非常

有谁知道一个迭代和有效的洪水填充算法?

或者有没有办法实现递归填充算法没有堆栈溢出错误?

试过一个@ Flood fill using a stack
但我找不到一种方法来处理白色和黑色的图像.

解决方法:

有人将J. Dunlap’s Queue-linear Flood Fill算法移植到androID here.我已经尝试了它并且速度非常快.

我修改了copyImage()方法,该方法最初使用了作者未提供的名为UtilitIEs的类.

public class QueuelinearFloodFiller {    protected Bitmap image = null;    protected int[] tolerance = new int[] { 0, 0, 0 };    protected int wIDth = 0;    protected int height = 0;    protected int[] pixels = null;    protected int fillcolor = 0;    protected int[] startcolor = new int[] { 0, 0, 0 };    protected boolean[] pixelsChecked;    protected Queue<FloodFillRange> ranges;    // Construct using an image and a copy will be made to fill into,    // Construct with BufferedImage and flood fill will write directly to    // provIDed BufferedImage    public QueuelinearFloodFiller(Bitmap img) {        copyImage(img);    }    public QueuelinearFloodFiller(Bitmap img, int targetcolor, int newcolor) {        useImage(img);        setFillcolor(newcolor);        setTargetcolor(targetcolor);    }    public voID setTargetcolor(int targetcolor) {        startcolor[0] = color.red(targetcolor);        startcolor[1] = color.green(targetcolor);        startcolor[2] = color.blue(targetcolor);    }    public int getFillcolor() {        return fillcolor;    }    public voID setFillcolor(int value) {        fillcolor = value;    }    public int[] getTolerance() {        return tolerance;    }    public voID setTolerance(int[] value) {        tolerance = value;    }    public voID setTolerance(int value) {        tolerance = new int[] { value, value, value };    }    public Bitmap getimage() {        return image;    }    public voID copyImage(Bitmap img) {        // copy data from provIDed Image to a BufferedImage to write flood fill        // to, use getimage to retrIEve        // cache data in member variables to decrease overhead of property calls        wIDth = img.getWIDth();        height = img.getHeight();        image = Bitmap.createBitmap(wIDth, height, Bitmap.Config.RGB_565);        Canvas canvas = new Canvas(image);        canvas.drawBitmap(img, 0, 0, null);        pixels = new int[wIDth * height];        image.getPixels(pixels, 0, wIDth, 1, 1, wIDth - 1, height - 1);    }    public voID useImage(Bitmap img) {        // Use a pre-existing provIDed BufferedImage and write directly to it        // cache data in member variables to decrease overhead of property calls        wIDth = img.getWIDth();        height = img.getHeight();        image = img;        pixels = new int[wIDth * height];        image.getPixels(pixels, 0, wIDth, 1, 1, wIDth - 1, height - 1);    }    protected voID prepare() {        // Called before starting flood-fill        pixelsChecked = new boolean[pixels.length];        ranges = new linkedList<FloodFillRange>();    }    // Fills the specifIEd point on the bitmap with the currently selected fill    // color.    // int x, int y: The starting coords for the fill    public voID floodFill(int x, int y) {        // Setup        prepare();        if (startcolor[0] == 0) {            // ***Get starting color.            int startPixel = pixels[(wIDth * y) + x];            startcolor[0] = (startPixel >> 16) & 0xff;            startcolor[1] = (startPixel >> 8) & 0xff;            startcolor[2] = startPixel & 0xff;        }        // ***Do first call to floodfill.        linearFill(x, y);        // ***Call floodfill routine while floodfill ranges still exist on the        // queue        FloodFillRange range;        while (ranges.size() > 0) {            // **Get Next Range Off the Queue            range = ranges.remove();            // **Check Above and Below Each Pixel in the Floodfill Range            int downPxIDx = (wIDth * (range.Y + 1)) + range.startX;            int uppxIDx = (wIDth * (range.Y - 1)) + range.startX;            int upY = range.Y - 1;// so we can pass the y coord by ref            int downY = range.Y + 1;            for (int i = range.startX; i <= range.endX; i++) {                // *Start Fill Upwards                // if we're not above the top of the bitmap and the pixel above                // this one is within the color tolerance                if (range.Y > 0 && (!pixelsChecked[uppxIDx])                        && CheckPixel(uppxIDx))                    linearFill(i, upY);                // *Start Fill Downwards                // if we're not below the bottom of the bitmap and the pixel                // below this one is within the color tolerance                if (range.Y < (height - 1) && (!pixelsChecked[downPxIDx])                        && CheckPixel(downPxIDx))                    linearFill(i, downY);                downPxIDx++;                uppxIDx++;            }        }        image.setPixels(pixels, 0, wIDth, 1, 1, wIDth - 1, height - 1);    }    // Finds the furthermost left and right boundarIEs of the fill area    // on a given y coordinate, starting from a given x coordinate, filling as    // it goes.    // Adds the resulting horizontal range to the queue of floodfill ranges,    // to be processed in the main loop.    // int x, int y: The starting coords    protected voID linearFill(int x, int y) {        // ***Find left Edge of color Area        int lFillLoc = x; // the location to check/fill on the left        int pxIDx = (wIDth * y) + x;        while (true) {            // **fill with the color            pixels[pxIDx] = fillcolor;            // **indicate that this pixel has already been checked and filled            pixelsChecked[pxIDx] = true;            // **de-increment            lFillLoc--; // de-increment counter            pxIDx--; // de-increment pixel index            // **exit loop if we're at edge of bitmap or color area            if (lFillLoc < 0 || (pixelsChecked[pxIDx]) || !CheckPixel(pxIDx)) {                break;            }        }        lFillLoc++;        // ***Find Right Edge of color Area        int rFillLoc = x; // the location to check/fill on the left        pxIDx = (wIDth * y) + x;        while (true) {            // **fill with the color            pixels[pxIDx] = fillcolor;            // **indicate that this pixel has already been checked and filled            pixelsChecked[pxIDx] = true;            // **increment            rFillLoc++; // increment counter            pxIDx++; // increment pixel index            // **exit loop if we're at edge of bitmap or color area            if (rFillLoc >= wIDth || pixelsChecked[pxIDx] || !CheckPixel(pxIDx)) {                break;            }        }        rFillLoc--;        // add range to queue        FloodFillRange r = new FloodFillRange(lFillLoc, rFillLoc, y);        ranges.offer(r);    }    // Sees if a pixel is within the color tolerance range.    protected boolean CheckPixel(int px) {        int red = (pixels[px] >>> 16) & 0xff;        int green = (pixels[px] >>> 8) & 0xff;        int blue = pixels[px] & 0xff;        return (red >= (startcolor[0] - tolerance[0])                && red <= (startcolor[0] + tolerance[0])                && green >= (startcolor[1] - tolerance[1])                && green <= (startcolor[1] + tolerance[1])                && blue >= (startcolor[2] - tolerance[2]) && blue <= (startcolor[2] + tolerance[2]));    }    // Represents a linear range to be filled and branched from.    protected class FloodFillRange {        public int startX;        public int endX;        public int Y;        public FloodFillRange(int startX, int endX, int y) {            this.startX = startX;            this.endX = endX;            this.Y = y;        }    }}@H_419_19@

如果您不希望UI等待图像填充,您也可以使用线程.

public class FloodFillThread extends Thread {    ProgressDialog mProgressDialog;    Bitmap mBitmap;    int mTargetcolor;    int mNewcolor;    Point mPoint;    Runnable mCallback;    public FloodFillThread(ProgressDialog pd, Runnable callback, Bitmap bitmap,            Point pt, int targetcolor, int newcolor) {        mBitmap = bitmap;        mPoint = pt;        mTargetcolor = targetcolor;        mNewcolor = newcolor;        mProgressDialog = pd;        mCallback = callback;    }    @OverrIDe    public voID run() {        QueuelinearFloodFiller filler = new QueuelinearFloodFiller(mBitmap, mTargetcolor, mNewcolor);        filler.setTolerance(10);        filler.floodFill(mPoint.x, mPoint.y);        handler.sendEmptyMessage(0);    }    private Handler handler = new Handler() {        @OverrIDe        public voID handleMessage(Message msg) {            mProgressDialog.dismiss();            mCallback.run();        }    };}@H_419_19@          总结       

以上是内存溢出为你收集整理的java – Android泛洪填充算法全部内容,希望文章能够帮你解决java – Android泛洪填充算法所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址:https://54852.com/web/1103312.html

(0)
打赏 微信扫一扫微信扫一扫 支付宝扫一扫支付宝扫一扫
上一篇 2022-05-28
下一篇2022-05-28

发表评论

登录后才能评论

评论列表(0条)

    保存