Oliver Hausler
Oliver Hausler

Reputation: 4977

Can I draw alpha using just one bitmap?

I have the following code to draw on a canvas. That code is taken from SO and Android SDK demos and I have skimmed it down to better explain my problem. The code is essentially working, but it makes older parts of the alpha drawings get darker over time because it draws the bitmap over and over in onDraw() (which is not a problem while using solid lines as demonstrated in the SDK, but which becomes one when using alpha).

Drawing

public class CanvasView extends View {

    public void init() {
        bitmap = Bitmap.createBitmap(1280, 720, Bitmap.Config.ARGB_8888); // a bitmap is created
        canvas = new Canvas(bitmap); // and a canvas is instantiated
    }

    // Events
    @Override public boolean onTouchEvent(@Nonnull MotionEvent event) {

        float x = event.getX(); float y = event.getY();

        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN: // when the user touches down
                path.reset(); // the previous path is reset (if any)
                drawingTool.down(); // my own class which encapsulates path.moveTo()
                break;

            case MotionEvent.ACTION_MOVE: // when the user paints
                Rect dirtyRect = drawingTool.move(x, y); // encapsulates path.quadTo() // the path is built
                if (dirtyRect != null) { invalidate(dirtyRect); } // and the dirty rectangle is invalidated
                break;

            case MotionEvent.ACTION_UP: // when the user lifts the finger
                canvas.drawPath(path, paint); // the final path is drawn
                path.reset();
                invalidate(); // and the full area invalidated (just to make sure the final drawing looks as it should)
                break;
        }
        return true;
    }

    @Override protected void onDraw(@Nonnull Canvas canvas) { // after every move or up event
        super.onDraw(canvas);

        canvas.drawBitmap(bitmap, 0, 0, null); // the previous bitmap is drawn [here is the problem]
        canvas.drawPath(path, paint); // and the new path is added
    }
}

The problem happens in onDraw(), because the bitmap is drawn over and over. So every time a new path is finished, the previous drawing becomes darker.

I know I could take a second bitmap and cache the results after each path is drawn, and then apply that "clean" bitmap for each new path. But this would be expensive.

Is there a way to draw alpha lines without using a second bitmap or re-drawing everything after each path? I am looking for an inexpensive solution.

Problem here is that bitmap and canvas are directly coupled, so when I draw on the canvas, the result immediately reflects in the bitmap. So I can't just clear one or the other?

Upvotes: 0

Views: 509

Answers (2)

Oliver Hausler
Oliver Hausler

Reputation: 4977

I played with this for some time and I realized that the solution is as simple as switching the two commands in onDraw.

Instead of

    canvas.drawBitmap(bitmap, 0, 0, null);
    canvas.drawPath(path, paint);

use

    canvas.drawPath(path, paint);
    canvas.drawBitmap(bitmap, 0, 0, null);

Drawing the bitmap last solves the problem. It is still too dark while being painted, so it needs some more tweaking, but the main problem is solved.

Plus, the good thing about it is that I won't need a second bitmap. But it is also clear that a second bitmap wouldn't have made much sense, as my bitmap is caching the image already and onDraw() just draws it into the view.

Upvotes: 1

QArea
QArea

Reputation: 4981

Actually you can set alpha level to Paint object. For example:

Paint transparentpaint = new Paint();
transparentpaint.setAlpha(100); // 0 - 255

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

Try to paste this instead of canvas.drawBitmap(bitmap, 0, 0, null);

Upvotes: 0

Related Questions