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;
}
}
}