Problems drawing a bitmap on a layout

2019-08-30 01:27发布

问题:

I create the Layout programatically in onCreate:

new Handler().postDelayed(new Runnable() {

        @Override
        public void run() {
            myView = new MyView(SketchActivity.this, layout.getWidth(), layout.getHeight());

            layout2.addView(myView);
            layout2.bringToFront();

        }
    }, 50);

The View where i create the (mutable?) bitmap:

public MyView(Context c, int width, int height) {
        super(c);

        WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        int w = display.getWidth(); // deprecated
        int h = display.getHeight();
        setFocusable(true);
        setBackgroundResource(R.drawable.download);

        // setting paint
        mPaint = new Paint();
        mPaint.setAlpha(0);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        mPaint.setAntiAlias(true);

        // getting image from resources
        Resources r = this.getContext().getResources();

        Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.smoke);

        // converting image bitmap into mutable bitmap

        bitmap = bm.createBitmap(w, h, Config.ARGB_8888);
        mCanvas = new Canvas();
        mCanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
        mCanvas.drawBitmap(bm, 0, 0, null);

    }

My onDraw function:

 @Override
    protected void onDraw(Canvas canvas) {
        mCanvas.drawCircle(x, y, r, mPaint);

        canvas.drawBitmap(bitmap, 0, 0, null);

        super.onDraw(canvas);

    }

OnTouchEvent:

@Override
    public boolean onTouchEvent(MotionEvent event) {
        x = (int) event.getX();
        y = (int) event.getY();

        r = 20;
        // Atlast invalidate canvas
        invalidate();

        return true;
    }

No LogCat Errors The problem is in myView. when i create the bitmap bitmap = bm.createBitmap(w, h, Config.ARGB_8888); If i put instead of w,h(width and height of screen) a small number Example: bitmap = bm.createBitmap(20, 20, Config.ARGB_8888); it creates a tiny picture. But if I put w and h, then instead of drawing on all the layout, it only draws on a small part. (even if i try: bitmap = bm.createBitmap(800, 1080, Config.ARGB_8888); it still draws on a small part, instead of all the screen. What should i do?

回答1:

This solved it:

public Bitmap getResizedBitmap(Bitmap bm, int newHeight, int newWidth) {
    int width = bm.getWidth();
    int height = bm.getHeight();
    float scaleWidth = ((float) newWidth) / width;
    float scaleHeight = ((float) newHeight) / height;
    // CREATE A MATRIX FOR THE MANIPULATION
    Matrix matrix = new Matrix();
    // RESIZE THE BIT MAP
    matrix.postScale(scaleWidth, scaleHeight);
    // RECREATE THE NEW BITMAP
    Bitmap resizedBitmap = Bitmap.createBitmap(bm, 0, 0, width, height, matrix, false);
    return resizedBitmap;
}

public MyView(Context c, int width, int height) {
        super(c);

        WindowManager wm = (WindowManager) c.getSystemService(Context.WINDOW_SERVICE);
        Display display = wm.getDefaultDisplay();
        int w = display.getWidth(); // deprecated
        int h = display.getHeight();
        setFocusable(true);
        setBackgroundResource(R.drawable.download);

        // setting paint
        mPaint = new Paint();
        mPaint.setAlpha(0);
        mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.DST_IN));
        mPaint.setAntiAlias(true);
        mPaint.setMaskFilter(new BlurMaskFilter(8, BlurMaskFilter.Blur.NORMAL));

        // getting image from resources
        Resources r = this.getContext().getResources();

        Bitmap bm = BitmapFactory.decodeResource(getResources(), R.drawable.smoke);
        Bitmap bm2 = getResizedBitmap(bm, h, w);

        // converting image bitmap into mutable bitmap

        bitmap = bm2.createBitmap(w, h, Config.ARGB_8888);
        mCanvas = new Canvas();
        mCanvas.setBitmap(bitmap); // drawXY will result on that Bitmap
        mCanvas.drawBitmap(bm2, 0, 0, null);

    }


回答2:

Looks like you're recycling your Bitmap somwhere in the code. There is a problem.

Yes, you should recycle it, but it's always a bit risky.

EDIT

Looks like you're drawing onto Bitmap. If it's not what you're trying to do, then you shouldn't call onDraw manually. Instead call invalidate() when you want to redraw your view.



回答3:

You need to add an Options data like this:

Options options = new Options();
options.isMutable = true; // works from api 11

mBitmap = BitmapFactory.decodeResource(getResources(), R.drawable.smoke, options);