首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Android -画布黑色当使用洪水填充

Android -画布黑色当使用洪水填充
EN

Stack Overflow用户
提问于 2014-12-17 15:14:49
回答 2查看 998关注 0票数 24

当我实现我的flood-fill类时,它会使整个Bitmap变成黑色。显然,这不是期望的效果。我看过以下线程:

据我所见,我正在做他们在这些解决方案中想出的一切,然而,它并没有为我的问题找到一个解决方案。因此,这里有一些简单的解释,让我们来讨论一下。

XML

我使用一个相对的布局和定位(堆叠)两个ImageViews直接在对方之上。他们都有相同的形象,这创造了一个错觉,你可以画的形象。然而,实际上,您只是在绘制一个透明的覆盖层。

代码语言:javascript
复制
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:orientation="horizontal" >

    ....

    <ImageView
        android:id="@+id/drawContainer2"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_toRightOf="@id/imageMapperSurfaces"
        android:contentDescription="@string/image" />

    <ImageView
        android:id="@+id/drawContainer"
        android:layout_width="match_parent"
        android:layout_height="match_parent"
        android:layout_toRightOf="@id/imageMapperSurfaces"
        android:contentDescription="@string/image" />

   ...
</RelativeLayout>

画布

然后我用这段代码创建我的Canvas,并确保正确地设置我的层类型。

代码语言:javascript
复制
public void setCanvas() {
    if(mFile != null && mFile.exists()) {
        mPictureBitmap = BitmapFactory.decodeFile(mFile.getAbsolutePath());
        mBitmap = Bitmap.createScaledBitmap(mPictureBitmap, mImageView.getWidth(), mImageView.getHeight(), false);
        mPictureBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true);
        mBitmap = mPictureBitmap.copy(Bitmap.Config.ARGB_8888, true);
        mSceneBitmap = mBitmap.copy(Bitmap.Config.ARGB_8888, true);
        mBlurBitmap = blurImage(mPictureBitmap); 
        mCanvas = new Canvas(mBitmap);
        mImageView.setImageBitmap(mBitmap);
        mImageView2.setImageBitmap(mPictureBitmap);
        mBlur.setImageBitmap(mBlurBitmap);

        // failure to set these layer types correctly will result in a black canvas after drawing.
        mImageView.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        mImageView2.setLayerType(View.LAYER_TYPE_HARDWARE, null);
        mImageView.bringToFront();
        mAllowedToDraw = true;

        setImageViewOnTouch();
    }
}

洪水-填充实现

我获取颜色,将我的参数传递给flood-fill对象,使用flood-fill方法,返回bitmap,最后将新的bitmap绘制到my canvas

代码语言:javascript
复制
int targetColor = mSceneBitmap.getPixel((int) event.getX(), (int) event.getY());
FloodFill fill = new FloodFill(mBitmap, targetColor, Color.argb(100, 255, 0, 0));
fill.floodFill((int) event.getX(), (int) event.getY());
Bitmap bmp = fill.getImage();
mCanvas.drawBitmap(bmp, 0, 0, null);
mImageView.invalidate();

洪水-填充类

锅炉板Flood-fill算法。

代码语言:javascript
复制
public class FloodFill {
    protected Bitmap mImage = null;
    protected int[] mTolerance = new int[] { 0, 0, 0, 0 };
    protected int mWidth = 0;
    protected int mHeight = 0;
    protected int[] mPixels = null;
    protected int mFillColor = 0;
    protected int[] mStartColor = new int[] { 0, 0, 0, 0 };
    protected boolean[] mPixelsChecked;
    protected Queue<FloodFillRange> mRanges;

    public FloodFill(Bitmap img) {
        copyImage(img);
    }

    public FloodFill(Bitmap img, int targetColor, int newColor) {
        useImage(img);

        setFillColor(newColor);
        setTargetColor(targetColor);
    }

    public void setTargetColor(int targetColor) {
        mStartColor[0] = Color.red(targetColor);
        Log.v("Red", "" + mStartColor[0]);
        mStartColor[1] = Color.green(targetColor);
        Log.v("Green", "" + mStartColor[1]);
        mStartColor[2] = Color.blue(targetColor);
        Log.v("Blue", "" + mStartColor[2]);
        mStartColor[3] = Color.alpha(targetColor);
        Log.v("Alpha", "" + mStartColor[3]);
    }

    public int getFillColor() {
        return mFillColor;
    }

    public void setFillColor(int value) {
        mFillColor = value;
    }

    public int[] getTolerance() {
        return mTolerance;
    }

    public void setTolerance(int[] value) {
        mTolerance = value;
    }

    public void setTolerance(int value) {
        mTolerance = new int[] { value, value, value, value };
    }

    public Bitmap getImage() {
        return mImage;
    }

    public void copyImage(Bitmap img) {
        mWidth = img.getWidth();
        mHeight = img.getHeight();

        mImage = Bitmap.createBitmap(mWidth, mHeight, Bitmap.Config.ARGB_8888);
        Canvas canvas = new Canvas(mImage);
        canvas.drawBitmap(img, 0, 0, null);

        mPixels = new int[mWidth * mHeight];

        mImage.getPixels(mPixels, 0, mWidth, 0, 0, mWidth, mHeight);
    }

    public void useImage(Bitmap img) {
        mWidth = img.getWidth();
        mHeight = img.getHeight();
        mImage = img;

        mPixels = new int[mWidth * mHeight];

        mImage.getPixels(mPixels, 0, mWidth, 0, 0, mWidth, mHeight);
    }

    protected void prepare() {
        mPixelsChecked = new boolean[mPixels.length];
        mRanges = new LinkedList<FloodFillRange>();
    }

    public void floodFill(int x, int y) {
        // Setup
        prepare();

        if (mStartColor[0] == 0) {
            // ***Get starting color.
            int startPixel = mPixels[(mWidth * y) + x];
            mStartColor[0] = (startPixel >> 16) & 0xff;
            mStartColor[1] = (startPixel >> 8) & 0xff;
            mStartColor[2] = startPixel & 0xff;
        }

        LinearFill(x, y);
        FloodFillRange range;

        while (mRanges.size() > 0) {
            range = mRanges.remove();
            int downPxIdx = (mWidth * (range.Y + 1)) + range.startX;
            int upPxIdx = (mWidth * (range.Y - 1)) + range.startX;
            int upY = range.Y - 1;
            int downY = range.Y + 1;

            for (int i = range.startX; i <= range.endX; i++) {
                if (range.Y > 0 && (!mPixelsChecked[upPxIdx]) && CheckPixel(upPxIdx)) LinearFill(i, upY);
                if (range.Y < (mHeight - 1) && (!mPixelsChecked[downPxIdx]) && CheckPixel(downPxIdx)) LinearFill(i, downY);
                downPxIdx++;
                upPxIdx++;
            }
        }

        mImage.setPixels(mPixels, 0, mWidth, 0, 0, mWidth, mHeight);
    }

    protected void LinearFill(int x, int y) {
        int lFillLoc = x;
        int pxIdx = (mWidth * y) + x;

        while (true) {
            mPixels[pxIdx] = mFillColor;
            mPixelsChecked[pxIdx] = true;
            lFillLoc--;
            pxIdx--;

            if (lFillLoc < 0 || (mPixelsChecked[pxIdx]) || !CheckPixel(pxIdx)) {
                break;
            }
        }

        lFillLoc++;
        int rFillLoc = x; 

        pxIdx = (mWidth * y) + x;

        while (true) {
            mPixels[pxIdx] = mFillColor;
            mPixelsChecked[pxIdx] = true;

            rFillLoc++;
            pxIdx++;

            if (rFillLoc >= mWidth || mPixelsChecked[pxIdx] || !CheckPixel(pxIdx)) {
                break;
            }
        }

        rFillLoc--;

        FloodFillRange r = new FloodFillRange(lFillLoc, rFillLoc, y);

        mRanges.offer(r);
    }

    protected boolean CheckPixel(int px) {
        int red = (mPixels[px] >>> 16) & 0xff;
        int green = (mPixels[px] >>> 8) & 0xff;
        int blue = mPixels[px] & 0xff;
        int alpha = (Color.alpha(mPixels[px]));

        return (red >= (mStartColor[0] - mTolerance[0]) && red <= (mStartColor[0] + mTolerance[0])
                && green >= (mStartColor[1] - mTolerance[1]) && green <= (mStartColor[1] + mTolerance[1])
                && blue >= (mStartColor[2] - mTolerance[2]) && blue <= (mStartColor[2] + mTolerance[2])
                && alpha >= (mStartColor[3] - mTolerance[3]) && alpha <= (mStartColor[3] + mTolerance[3]));
    }

    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;
        }
    }
}

就这样,我们应该有所有的拼图,但由于某种原因,它们不起作用。我不知所措,任何帮助都很感激。谢谢!

EN

回答 2

Stack Overflow用户

发布于 2015-05-20 16:50:20

我想你是在排队:

代码语言:javascript
复制
mCanvas.drawBitmap(bmp, 0, 0, null);

可能需要更像

代码语言:javascript
复制
mPaint = new Paint();    
mCanvas.drawBitmap(bmp, 0, 0, mPaint);
票数 0
EN

Stack Overflow用户

发布于 2015-09-12 23:20:12

我不确定所有的事情,但据我所能告诉你,我会尝试这些解决方案:

第一:我不使用decodeFile,而是使用decodeInputStream第二:因为有人已经告诉你,在显示视图时最好使用画图()。第三,我要问你为什么需要那个填充食物的算法?我认为它太滞后,它看起来有点凌乱使用,你为什么不创建一个新的缩放位图或类似于opengl的效果来做呢?因为这就是为什么会有显卡;

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27528766

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档