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.
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]
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);
- 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