Reputation: 525
ArrayList
ArrayList<Pair<Path, Float>> foregroundPaths = new ArrayList<Pair<Path, Float>>();
Paint initilization
mPaint = new Paint();
mPaint.setAntiAlias(false);
mPaint.setDither(true);
mPaint.setColor(0x0FFF0000);
mPaint.setStyle(Paint.Style.STROKE);
mPaint.setStrokeJoin(Paint.Join.BEVEL);
mPaint.setStrokeCap(Paint.Cap.ROUND);
mPaint.setStrokeWidth(Math.abs(ImageViewTouch.brushSize
/ getScale()));
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_ATOP));
mPaint.setAlpha(0x80);
OnDraw
canvas.save();
displayRectF = new RectF();
canvas.concat(getDisplayMatrix());
rect = canvas.getClipBounds();
displayRectF.set(rect);
for (Pair<Path, Float> p : foregroundPaths) {
mPaint.setStrokeWidth(p.second);
canvas.drawPath(p.first, mPaint);
}
canvas.restore();
Above codes are capable of drawing on canvas using finger. But the problem is when multiple path crossing each other its overlap. I have attached a link of my app snapshot. Overlapping is inside the green rectangle. I set Xfermode to paint but not working as i expect.
Please help me and suggest me, what should i do to remove this problem. any suggestion will be appreciated. Thanks
Upvotes: 0
Views: 2636
Reputation: 1
I had similar problem. I used:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.SRC_OVER));
It allows to draw pixels over the destination pixels without making path transparent.
Upvotes: 0
Reputation: 1
Since AvoidXferMode is depreciated, this would be helpful for people who are using API 16+. This is rather like a workaround. But works perfectly fine. This overlapping error occurs because of the alpha value set for paint.
For eg., If you want to use 'Red' color with alpha Instead of passing mPaint.setAlpha(), you could actually use utility function to set transparency to 'Red' color.
So in this case, just use mPaint.setColor(Color.parseColor(getTransparentColor(Color.Red, 50))); and don't use setAlpha.
Use below code to get transparent color.
public static String getTransparentColor (int colorCode, int transCode) {
// convert color code into hexa string and remove starting 2 digit
String color = defaultColor;
try{
color = Integer.toHexString(colorCode).toUpperCase().substring(2);
}catch (Exception ignored){}
if (!color.isEmpty() && transCode < 100) {
if (color.trim().length() == 6) {
return "#" + convert(transCode) + color;
} else {
Log.d(TAG, "Color is already with transparency");
return convert(transCode) + color;
}
}
// if color is empty or any other problem occur then we return deafult color;
return "#" + Integer.toHexString(defaultColorID).toUpperCase().substring(2);
}
/**
* This method convert numver into hexa number or we can say transparent code
*
* @param trans number of transparency you want
* @return it return hex decimal number or transparency code
*/
public static String convert(int trans) {
String hexString = Integer.toHexString(Math.round(255 * trans / 100));
return (hexString.length() < 2 ? "0" : "") + hexString;
}
Note: Even after all these changes if overlapping error occurs, then add the below code.
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
Upvotes: 0
Reputation: 525
mPaint.setXfermode(new AvoidXfermode(Color.RED, 90, Mode.AVOID));
it works for me.
Upvotes: 0
Reputation: 679
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.OVERLAY));
Upvotes: 0
Reputation: 433
Have you tried:
mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.XOR));
After all what you want is an exclusive OR (XOR) - either the first line or the second line, but not both on top of each other.
I have not tried this, just seems like the logical answer.
Upvotes: 1