How can I override onDraw so that I take what would have been drawn (as a bitmap) and transform it?

后端 未结 3 1363
再見小時候
再見小時候 2020-12-16 04:59

The method below works, but it unfortunately, this method involves creating a bitmap the size of the entire screen - not just the area that is drawn to. If I use this to dra

相关标签:
3条回答
  • 2020-12-16 05:38

    The following code will be much more efficient.

    public class MyView extends TextView{
        private Canvas offscreen;
    
        public MyView(Context context, AttributeSet attrs, int defStyle) {
            super(context, attrs, defStyle);
        }
    
        public MyView(Context context, AttributeSet attrs) {
            super(context, attrs);
        }
    
        public MyView(Context context) {
            super(context);
        }
    
        @Override
        protected void onDraw(Canvas canvas) {
            //We want the superclass to draw directly to the offscreen canvas so that we don't get an infinitely deep recursive call
            if(canvas==offscreen){
                super.onDraw(offscreen);
            }
            else{
                //Our offscreen image uses the dimensions of the view rather than the canvas
                Bitmap bitmap=Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
                offscreen=new Canvas(bitmap);
                super.draw(offscreen);
                //Create paint to draw effect
                Paint p=new Paint();
                p.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DARKEN));
                //Draw on the canvas. Fortunately, this class uses relative coordinates so that we don't have to worry about where this View is actually positioned.
                canvas.drawBitmap(bitmap, 0, 0, p);
            }
        }
    }
    
    0 讨论(0)
  • 2020-12-16 05:44

    I encountered something similar, where canvas.getWidth() and canvas.getHeight() returns the width and height of the whole screen instead of the view itself.

    Try to use the below instead:

    Bitmap bitmap=Bitmap.createBitmap(getWidth(), getHeight(), Config.ARGB_8888);
    

    For my case, getWidth() and getHeight() returns me the dimensions of my view. Good luck!

    0 讨论(0)
  • 2020-12-16 05:47

    Have you tried changing the size of the bitmap you create, to be only equal to the clip bounds rather than the entire size of the given canvas? I don't know if this is the case with all Views, but I found that the onDraw method for some Views is given a canvas as big as the screen, regardless of the actual size of the content. It then clips the canvas, restricting it to the top left corner only, draws there and then translates that part to somewhere else on the screen when it's actually ready to display the whole layout. In other words, despite it having a canvas the size of the whole screen, it only actually uses a small piece of it. So what you could try doing is instead of using

    Bitmap bitmap = Bitmap.createBitmap(canvas.getWidth(), canvas.getHeight(), ...)
    

    you could try

    Rect rect = canvas.getClipBounds();
    int width = rect.width();
    int height = rect.height();
    Bitmap bitmap = Bitmap.createBitmap(width, height, ...); 
    

    That way you reduce the overhead of working with a much larger bitmap than necessary. Note: I haven't actually tried doing this so it might not work, but it's worth trying.

    0 讨论(0)
提交回复
热议问题