PorterDuff Modes and Android

PorterDuff Modes

This is an article on the PorterDuff modes for Android. It’s mildly technical…

(whilst you are here, check out our apps in the Google Play Store)

We recently had a requirement to ‘grey’ out an image for an Android application. A quick look at some example code and we could see that a call to canvas.drawColor(…) would do the trick. However, the draw color defaulted to using a PorterDuff Mode of SRC_OVER.

Eh?

Not being grounded in Computer Science, the PorterDuff modes are a bit of a mystery to us. Never mind, we’ll look at the Android documentation for PorterDuff.Mode, an example of which is shown below:

public static final PorterDuff.Mode SRC_ATOP

[Da, Sc * Da + (1 – Sa) * Dc]

WTF?

This must be the most useless piece of Javadoc in Android. Whilst it’s technically correct, it could at least describe the effect of the mode!

A quick Google of Android and PorterDuff doesn’t really show any examples of what each mode does.

Wikipedia to the rescue

The Wikipedia article for PorterDuff, under Alpha Compositing, does show the effects of each of the modes. If we substitute Wikipedia’s A/B for Android’s SRC/DST then we can see a good correlation between them, unsurprisingly.

Armed with this information, we applied various modes to our image, but nothing seemed to work as expected. Obviously we’re doing something wrong. What we really need is an example of the different modes in use.

A quick Google search didn’t really reveal anything out there that gave us examples of this on Android.

We resigned ourselves to writing a quick example to find out what all the modes were.

Android to the rescue

Luckily enough, we came across the exact demo code we needed in an Android Sample. It’s cunningly hidden away in the Xfermode sample. We weren’t attempting to use Xfermodes, which is why our searches for PorterDuff probably didn’t highlight anything useful.

The example draws a couple of bitmaps, with the second bitmap drawn using a Paint instance that has the xfermode set. This wasn’t quite what we were after, so we re-did the example and used the canvas.drawColor() command we were really after.

As per the Android example, the background is cross hatched and the yellow bitmap are drawn to the canvas first. We then clip the canvas and fill the background with our colour, e.g.

canvas.clipRect(W / 3, H / 3, W, H);
canvas.drawColor(0x88aaaaaa, pdModes[i]);

This creates a nice example that shows how the PorterDuff modes should look, see the image below. Now, if we could only get this to work in the real code…

Interesting things to note:

  • The SRC is actually the rectangle, even though this is drawn last (We’d expected this to be the DST)
  • There’s a bug report that suggests Xfermode doesn’t work with hardware acceleration, though it seems fine on our Galaxy Nexus
Advertisements

2 thoughts on “PorterDuff Modes and Android

  1. Well this does help quite a lot but I think you should have explained this in little more detail.
    About the javadoc page you are absolutely right it’s hilarious. Only funnier find in documentation I think is

    public static boolean isUserAMonkey ()

    Added in API level 8
    Returns “true” if the user interface is currently being messed with by a monkey.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s