4

I am working on a paint application for Android. Now I want to implement an eraser to allow erasing parts of a loaded bitmap by using touch input and making the bitmap transparent along the finger's path.

A very good example of what I try to achieve is shown in the application Steamy Window for Android. Steamy Window simulates a fogged window, where a user can wipe parts of the fog via touch input.

Any suggestions how I could implement the feature?

UPDATE: I have posted the most important sections of my current code below. I am not really happy with it for the following reasons:

  1. Drawing is quite sluggish. What can I improve here?

  2. I am looking for a way to use an alpha mask in order to set the pixel transparency/alpha of the pixels as I want to simulate a paint brush. Any suggestions how this could be achieved?

        public DrawView(Context context, String imageName) {

        super(context);

        // Get the overlay image and its dimensions
        Bitmap overlayImageOriginal = BitmapFactory.decodeResource(
                getResources(), R.drawable.overlay);
        width = overlayImageOriginal.getWidth();
        height = overlayImageOriginal.getHeight();

        // Get a copy of the overlay image and recycle the original
        overlayImage = overlayImageOriginal.copy(Config.ARGB_8888, true);
        overlayImageOriginal.recycle();

        // Get background image of this level
        int resId = getResources().getIdentifier(imageName, "drawable",
                "com.xxx");
        backgroundImage = BitmapFactory.decodeResource(getResources(), resId);

        // Copy pixels
        overlayImagePixels = new int[width * height];
        overlayImage.getPixels(overlayImagePixels, 0, width, 0, 0, width,
                height);

        getHolder().addCallback(this);
        _thread = new DrawThread(getHolder(), this);
        setFocusable(true);
    }

    @Override
    public boolean onTouchEvent(MotionEvent event) {
        synchronized (_thread.getSurfaceHolder()) {
            switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                touchStart(event.getX(), event.getY());
                return true;
            case MotionEvent.ACTION_MOVE:
                touchMove(event.getX(), event.getY());
                return true;
            case MotionEvent.ACTION_UP:
                touchStop();
                return true;
            }
            return false;
        }
    }

    @Override
    public void onDraw(Canvas canvas) {
       // draw the image to guess
       canvas.drawBitmap(backgroundImage, 0, 0, null);
       // apply user input to the overlay-image
       setRegionTransparency((int) mTouchX, (int) mTouchY, 20, 0);
       // draw the overlay-image (hiding the image to guess)
       canvas.drawBitmap(overlayImage, 0, 0, null);
    }


    /**
     * 
     * @param posX
     * @param posY
     * @param radius
     * @param alpha - 0: full transparent, 255: full opaque
     */
    private void setRegionTransparency(int posX, int posY, int radius, int alpha) {
        int left = posX - radius;
        int right = posX + radius;
        int top = posY - radius;
        int bottom = posY + radius;
        int color = 0;

        // onDraw() is called before any user input
        // -> assume 0/0 as invalid arguments
        if (posX == 0 && posY == 0) {
              return;
        }

        // TODO currently only rectangular area is supported
        // but we need circular
        // we should use a pre-made alpha mask with smoothed edges
        // we should take into account: pressure and/or duration of touch

        for (int y = top; y = 0 && y = 0 && x = TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
            mPath.quadTo(mTouchX, mTouchY, (x + mTouchX) / 2, (y + mTouchY) / 2);
            mTouchX = x;
            mTouchY = y;
        }
    }
}


Philipp
  • 788
  • 1
  • 11
  • 23
  • What is the background supposed to look like? What you can do is draw the background on top of the foreground at the needed locations. – Maz Jul 23 '10 at 15:02
  • have you tried to add an alpha with the onDraw method? you get the pixel color, and you change its alpha somewhere between 00 and FF? – Sephy Jul 23 '10 at 15:30
  • I plan to use two bitmaps: one as foreground and one as background. Parts of the overlaying bitmap are supposed to get "erased" while drawing i.e. the alpha value of the pixels of the overlaying bitmap is changed. – Philipp Jul 28 '10 at 10:45
  • you got a solution for that meanwhile? – Mathias Conradt Oct 30 '10 at 09:54
  • @Mathias: Yep, i found a solution similar to the one described in your answer, check out: http://stackoverflow.com/questions/3467334/erase-bitmap-parts-using-porterduff-mode – Philipp Nov 04 '10 at 08:50

1 Answers1

2

Take a look at

Making Overlaid image transparent on touch in Android?

Community
  • 1
  • 1
Mathias Conradt
  • 28,420
  • 21
  • 138
  • 192