How to get canvas pixel

2019-03-31 01:44发布

问题:

I have a canvas on which I draw lines:

//see code upd

I need to make the pipette tool which will take color from my canvas. How may I make it?


Code upd:

private static class DrawView extends View 
{
        ...
        public DrawView(Context context) {
            super(context);
            setFocusable(true);

            mBitmap = Bitmap.createBitmap(640, 860, Bitmap.Config.ARGB_8888);
            mCanvas = new Canvas(mBitmap);
            mPath = new Path();
            mBitmapPaint = new Paint(Paint.DITHER_FLAG);

            this.setDrawingCacheEnabled(true);
        }

        @Override
        protected void onDraw(Canvas canvas) {
            canvas.drawColor(0xFFAAAAAA);
            canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
            canvas.drawPath(mPath, mPaint);
        }
        private void touch_up()
        {
            if(!drBool) //is true when I click pipette button
            {
                ...
                mCanvas.drawPath(mPath, mPaint); // lines draw
                mPath.reset();
            }else{
                this.buildDrawingCache();
                cBitmap = this.getDrawingCache(true);
                if(cBitmap != null)
                {
                    int clr = cBitmap.getPixel((int)x, (int)y);
                    Log.v("pixel", Integer.toHexString(clr));
                    mPaint.setColor(clr);
                }else{
                    Log.v("pixel", "null");
                }
            }
            drBool = false;
        }
    }

I see only "pixel"-"ffaaaaaa", or if I use mCanvas.drawColor(Color.GRAY) "pixel"-"ff888888"

回答1:

A canvas is nothing more than a container which holds drawing calls to manipulate a bitmap. So there is no concept of "taking colour from a canvas".

Instead, you should examine the pixels of the bitmap of the view, which you can get with getDrawingCache.

In your views' constructor:

this.setDrawingCacheEnabled(true);

When you want the colour of a pixel:

this.buildDrawingCache();
this.getDrawingCache(true).getPixel(x,y);

This is very inefficient if you are calling it many times in which case, you might want to add a bitmap field and use getDrawingCache() to set it in ondraw().

private Bitmap bitmap;

...

onDraw()

  ...

  bitmap = this.getDrawingCache(true);

Then use bitmap.getPixel(x,y);



回答2:

Above answer returns me blank bitmap. This is my solution

@Override
protected void onDraw(Canvas canvas) {
    ...
    bitmapUpdated = true;
}

And then for getting bitmap

public Bitmap getBitmapImage() {
    if (bitmapUpdated) {
        this.buildDrawingCache();
        bitmapImage = Bitmap.createBitmap(this.getDrawingCache());
        this.destroyDrawingCache();
    }
    return bitmapImage;
}

This works fine for me, without excessive overhead.

Perhaps better solution would be to override invalidate() and onDraw() so it uses your canvas, that is linked with your bitmap

Bitmap b = Bitmap.createBitmap(v.getWidth(), v.getHeight(), Bitmap.Config.ARGB_8888);
Canvas c = new Canvas(b);
v.draw(c);
return b;