4

I'm trying to replace a color for something that is drawn on a Canvas using AvoidXferMode. From the android docs it looks like it's exactly what I need:

AvoidXfermode xfermode will draw the src everywhere except on top of the opColor or, depending on the Mode, draw only on top of the opColor.

What I'm trying is something like this:

Paint paint = new Paint();
paint.setColor(Color.RED);
canvas.drawPaint(paint); // actually drawing a bitmap here
paint.setXferMode(new AvoidXferMode(Color.RED, 0, TARGET);
paint.setColor(Color.GREEN);
canvas.drawPaint(paint);

However, this just gives a red screen, not green as I would expect (replacing the red with green). I guess I'm missing the point some where...Any suggestions?

botteaap
  • 5,790
  • 3
  • 29
  • 35

2 Answers2

5

I finally found out what is issue is, there are some clues here: AvoidXferMode Tolerance but it really hit me when I read this post http://stuffthathappens.com/blog/2010/06/04/android-color-banding/ by Eric Burke. The tolerance is failing because the view canvas is not in 8888 mode.

That means that when you draw a color or bitmap on that canvas the colors get converted to the target pixel format and the color might slightly change. To fix this you can either switch the entire window pixel format as seen in Eric's post or you can draw onto a 8888 back buffer.

Unfortunately the link to Eric's post is dead, but Roman Guy also has a similar write up here: http://www.curious-creature.org/2010/12/08/bitmap-quality-banding-and-dithering/

Community
  • 1
  • 1
botteaap
  • 5,790
  • 3
  • 29
  • 35
  • Link to Eric Burke's page is now dead. – Trevor Aug 15 '12 at 22:06
  • @Trevor Updated the post, you could have corrected it in stead of downvoting it. The gist of the solution is not in the link but in the answer itself. – botteaap Aug 17 '12 at 06:55
  • Many thanks for clarifying - now upvoted. Sorry, but I didn't correct it myself because I genuinely didn't get the complete picture from your answer without being able to see Eric's page. – Trevor Aug 17 '12 at 10:18
0

I'm currently having the same problem but I got it working by specifying 255 as tolerance instead. According to the API documentation this is wrong (It should draw the destination EVERYWHERE with this full-tolerance setting) but for some reason the value 255 does exactly what the value 0 should do.

kayahr
  • 20,913
  • 29
  • 99
  • 147
  • It doesn't seem to work for me, setting the tolerance to 255 affects the whole image, not only the target color...could you post some sample code? – botteaap Mar 31 '10 at 15:56
  • Yeah, you are right. This depends on the color. My example worked with RED and BLUE on a BLACK background. Tolerance of 255 works then (at least for me) but if you use LTGRAY and DKGRAY for example then it fails. You can find my code here: http://stackoverflow.com/questions/2553694/avoidxfermode-tolerance I gave up with this AvoidXferMode and used PorterDuffXfermode instead with SRC_IN and SRC_OUT mode. – kayahr Apr 01 '10 at 13:50