ravi roshan
ravi roshan

Reputation: 525

color overlapping when drawing multiple path

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();

enter image description here

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

Answers (5)

Marcin Siwak
Marcin Siwak

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

Monika Mohan
Monika Mohan

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

ravi roshan
ravi roshan

Reputation: 525

mPaint.setXfermode(new AvoidXfermode(Color.RED, 90, Mode.AVOID)); 

it works for me.

Upvotes: 0

Oleksandr Berdnikov
Oleksandr Berdnikov

Reputation: 679

mPaint.setXfermode(new PorterDuffXfermode(PorterDuff.Mode.OVERLAY));

Upvotes: 0

Gesh
Gesh

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

Related Questions