[Android Software Development] imso:
As what was stated on the header I want to implement either a "paint" function for user to edit paint/censor unwanted parts of a photo displayed on a imageview before uploading it to a server in the edited format and a redo function if user makes a mistake while editing?

How do I come about doing it, I've read relevant topics on Canvas, or FingerPaint but still puzzled on how to implement it based on my project here? Tried referencing to the links here and here but without success in implementing the codes into my project code due to my lack of programming skills.

Thanks for any help rendered!

Tried integrating the codes below into my code above (image preview after taking a photo with the camera) for user to start editing via painting but still not working? Thanks for any help rendered!

public class Drawing extends View {
private Paint mPaint, mBitmapPaint;
Intent intent = getIntent();
Bitmap mBitmap = (Bitmap) intent.getParcelableExtra("BitmapImage");
private Canvas mCanvas;
private Path mPath;

private float mX, mY;
private static final float TOUCH_TOLERANCE = 4;

private int color, size, state;

private ArrayList<Path> paths = new ArrayList<Path>();
private ArrayList<Path> undonePaths = new ArrayList<Path>();
private ArrayList<Integer> colors = new ArrayList<Integer>();
private ArrayList<Integer> sizes = new ArrayList<Integer>();

public Drawing(Context c) {
super(c);
}

public Drawing(Context c,int width, int height, int size, int color, int state) {
super(c);

mBitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888);
mCanvas = new Canvas(mBitmap);
mPath = new Path();

mPaint = new Paint();
mPaint.setAntiAlias(true);
mPaint.setDither(true);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.ROUND);
mPaint.setStrokeCap(Paint.Cap.ROUND);

// mBitmapPaint = new Paint(Paint.DITHER_FLAG);
// mBitmapPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC));

setColor(color);
setSize(size);
setState(state);
}

@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
}

@Override
protected void onDraw(Canvas canvas) {
// canvas.drawColor(Color.TRANSPARENT);
// canvas.drawBitmap(mBitmap, 0, 0, mBitmapPaint);
//
// if (state == 0)
// mBitmap.eraseColor(Color.TRANSPARENT);

for (int i = 0; i < paths.size(); i++) {
mPaint.setColor(colors.get(i));
mPaint.setStrokeWidth(sizes.get(i));
canvas.drawPath(paths.get(i), mPaint);
}
mPaint.setColor(color);
mPaint.setStrokeWidth(size);
canvas.drawPath(mPath, mPaint);

}

public void setColor(int color) {
this.color = color;
}

public void setSize(int size) {
this.size = size;
}

public void setState(int state) {
this.state = state;
// if (state == 0)
// mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.CLEAR));
// else
// mPaint.setXfermode(null);
}

public void onClickUndo() {
if (paths.size() > 0) {
undonePaths.add(paths.remove(paths.size() - 1));
sizes.remove(sizes.size() - 1);
colors.remove(colors.size() - 1);
invalidate();
}
}

private void touch_start(float x, float y) {
undonePaths.clear();
mPath.reset();
mPath.moveTo(x, y);
mX = x;
mY = y;
}

private void touch_move(float x, float y) {
float dx = Math.abs(x - mX);
float dy = Math.abs(y - mY);
if (dx >= TOUCH_TOLERANCE || dy >= TOUCH_TOLERANCE) {
mPath.quadTo(mX, mY, (x + mX) / 2, (y + mY) / 2);
mX = x;
mY = y;
}
}

private void touch_up() {
mPath.lineTo(mX, mY);
mCanvas.drawPath(mPath, mPaint);

colors.add(color);
sizes.add(size);
paths.add(mPath);
mPath = new Path();
}

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

switch (event.getAction()) {
case MotionEvent.ACTION_DOWN:
touch_start(x, y);
invalidate();
break;
case MotionEvent.ACTION_MOVE:
touch_move(x, y);
invalidate();
break;
case MotionEvent.ACTION_UP:
touch_up();
invalidate();
break;
}
return true;
}
}