I am working on a function that drawing some transparent line on the canvas, the problem is , there is some "ball shape" on the line as the screenshot show.
Here is my code:
canvas = new Canvas(alteredBitmap);
paint = new Paint();
paint.setAntiAlias(true);
paint.setStrokeWidth(width);
paint.setColor(color);
paint.setStyle(Paint.Style.STROKE);
paint.setStrokeJoin(Paint.Join.ROUND);
paint.setStrokeCap(Paint.Cap.ROUND);
paint.setAlpha(alpha);
matrix_draw = new Matrix();
canvas.drawBitmap(bmp, matrix_draw, paint);
setImageBitmap(alteredBitmap);
press the button to set alpha
public void setAlpha(int alpha) {
this.alpha = alpha;
paint.setAlpha(alpha);
}
And the listener
drawListener = new OnTouchListener() {
@Override
public boolean onTouch(View v, MotionEvent event) {
int action = event.getAction();
switch (action) {
case MotionEvent.ACTION_DOWN:
downx = getPointerCoords(event)[0];// event.getX();
downy = getPointerCoords(event)[1];// event.getY();
break;
case MotionEvent.ACTION_MOVE:
upx = getPointerCoords(event)[0];// event.getX();
upy = getPointerCoords(event)[1];// event.getY();
canvas.drawLine(downx, downy, upx, upy, paint);
invalidate();
downx = upx;
downy = upy;
break;
case MotionEvent.ACTION_UP:
// upx = getPointerCoords(event)[0];// event.getX();
// upy = getPointerCoords(event)[1];// event.getY();
// canvas.drawLine(downx, downy, upx, upy, paint);
// invalidate();
break;
case MotionEvent.ACTION_CANCEL:
break;
default:
break;
}
return true;
}
};
final float[] getPointerCoords(MotionEvent e) {
final int index = e.getActionIndex();
final float[] coords = new float[] { e.getX(index), e.getY(index) };
Matrix matrix = new Matrix();
getImageMatrix().invert(matrix);
matrix.postTranslate(getScrollX(), getScrollY());
matrix.mapPoints(coords);
return coords;
}
Thanks a lot for helping
The ball shapes are where each line segment overlaps the previous one. You can fix this by using a second image overlaid on top of the image that you are editing.
Initialize the overlay image to completely transparent and make it the same size as the image you are editing.
Inside
setAlpha()
set the alpha of the overlay image to the alpha value.When the user is drawing a line, in the
case MotionEvent.ACTION_MOVE
block, draw the line onto the overlay image instead, but at full opacity. Because all line segments are drawn at full opacity, there won't be any ball shapes where they overlap, but the line will still appear transparent because of the alpha value applied to the overlay image.In case
MotionEvent.ACTION_UP
, transfer the line onto the image by drawing the overlay image onto the target image using canvas draw calls, using the alpha value set insetAlpha()
, and then clear the overlay image to transparent.