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:
Drawing is quite sluggish. What can I improve here?
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; } } }