iOS Core Graphics vs Android Canvas API
In porting You Doodle to Android, I have become very familiar with the Android Canvas API, the OnDraw
function and the TextureView
class. While I can’t consider myself an expert yet in Android graphics I can say that I have enough experience to give a good comparison of how the Android Canvas API compares against Core Graphics on iOS.
The Android Canvas API is object oriented and contains a number of useful objects to manage painting operations as well as canvas state.
Core Graphics on the other hand is a C based API and is simply a large set of C functions that allow drawing operations.
There are only three categories worth comparing in my opinion, and they are performance, feature set and ease of use.
Performance
Core graphics wins hands down in my tests. Being a low level C API certainly helps I’m sure, but simple operations such as path drawing, rendering to an off screen bitmap and then rendering said off screen bitmap to a view are much faster with Core Graphics.
I have an iPad Air and a Nexus 7 2013 edition. The iPad Air can draw on a 4096×4096 (16 megapixel!) off screen bitmap and render that bitmap to the screen in a UIView at 60 fps. This works even inside a UIScrollView
! Zooming and panning are buttery smooth. I am using the iOS methods to invalidate the rect that changes every frame. Somehow iOS can quickly update just that rectangle without having to mess with the other bits of the image / texture.
The Nexus 7 has some stutter when drawing simple paths even with a 2048×2048 image. I am pretty astonished at how poorly Android handles drawing an off screen bitmap to the screen. Whatever code is doing this on Android needs to be optimized. Calling Invalidate with a rect does not help much at all, nor does using a TextureView
vs. a regular View
. It seems like Android is having to update the entire image / texture every frame, even when a rect is passed to Invalidate
. On older Android devices, rendering to a 2048×2048 off screen bitmap and showing it on screen is a painful, slow and a horrible experience.
If Android could improve the speed at which an off screen bitmap could be drawn to the screen in the OnDraw method, that would close the gap with Core Graphics, but for now there is a wide performance gap in my experience.
Winner: Core Graphics by a landslide
Feature Set
Both the Android Canvas API and Core Graphics offer a rich set of API’s. Both offer path drawing, clipping, masking, blending and state management.
Core graphics maintains it’s state internally, while the Android Canvas API uses a Canvas and Paint object, which makes things a little easier to work with.
The one thing I noticed is that Core Graphics offers more blend modes than the Android Canvas API. For example, kCGBlendModeColor
is a great one that allows re-coloring of images. I had to re-implement this blend mode from scratch on Android which was a lot of work.
Because Core Graphics offers more blend modes but otherwise has a comparable feature set, I give it a slight edge in this category.
Winner: Core Graphics by a nose
Ease of Use
Where the Android Canvas API really shines is in it’s clean, object oriented interface. Working with bitmaps, canvas and paint objects is much easier than Core Graphics, where everything is passed through a C function. It only took me a matter of days to feel very comfortable with the Android Canvas API, whereas Core Graphics took about a month.
Working with the Android Bitmap
class vs CGImageRef
objects is so much nicer. Memory management with the CGImage*
API’s is tricky.
To be fair, there are plenty of open source wrappers around Core Graphics and UIBezierPath
does make path operations less painful, but I’m comparing raw framework API’s here.
Winner: Android Canvas API
Conclusion
Because of it’s very poor performance, I am really disappointed in the Android Canvas API. I was hoping to get comparable performance to Core Graphics with drawing to an off screen bitmap and rendering it on screen, but alas it was not to be. I may end up having to drop down to raw OpenGL which is something I have really wanted to avoid because of it’s complexity.
Core Graphics for me wins hands down, and I wish it were available on Android.