<-- home

Display animated image on iOS device

Introduction

As we know, mainstream animated image formats(i.e.,gif,apng) can be abstracted into a set of segments,each segment includes an image and an extension.Because iOS official repository doesn’t offer us a function to handle this in a convenient way,to display such animated image on iOS device,we need to decode animated image into segments and display images one by one.

Our goal is to display animated image with low cpu and memory usage and giving users a better experience.

Issues

Extension difference

Because the extension of each image is different,we can’t set the parameter animationDuration animationImages in UIImageView and execute function startAnimating().UIImageView’s function only apply to same extension case.

Ios frame rate limit

Normally,the iOS device has frame rate limit,which is 60 frames per second. If the extension of each image is smaller than the diplay interval(1/FPS),there must be a few images that can’t be displayed.On the other hand,if the extension of each image is larger than the diplay interval,there must be a few images that is displayed more than one time.Furthermore,we need to handle the case that the extension of each image is much larger than the diplay interval.Ignore this case will casue a lot of useless display image function calls.

Device resources

Decoding image into CGImage will consume a lot of CPU’s resources.After decoding,the CGImage will consume a lot of memory’s resources(each image cosume width*length*4 byte memory resources).

Solutions

All those following solutions are implemented in animated gif & apng engine AImage.

Processing raw animated image

This step will handle issue Extension difference and Ios frame rate limit.

First,we define a parameter named Level of Integrity.

We said that an animated image can be abstracted into a set of segments,each segment includes an image and an extension. Imagine all those images to be cakes,cake’s length is the size of extension.Place those cakes side by side in order.

Then we need a fork.In the begining,we use a fork with distant tines to fork those cakes.There will be a few case s on the fork.Then,we shorten the interval of tines and fork cakes again,there will be more cases on the cake.We repeat this step until we can’t shorten the interval of tines or the number of cakes on the fork is greater than the number of all cakes multiply by the parameter Level of Integrity.

Finally,we got two objects,the the interval of tines and the set of cases that on the fork.These objects are mapped to a set of images that will be displayed, and one const parameter IntervalTime of those image.

Time&Frame

Though this step,we handle issue Extension difference,and will have a better performance in the case that the extension of each image is much larger than the diplay interval.

Displaying animated image

This step will handle issue Device resources.

Handle memory usage issue.As we can see,after decoding image,CGImagewill consume a lot of memory’s resources.It is clear that we can’t decode all the images at the same time when the animated image’s size is large(like more than 300KB).Don’t cache those CGImage seems like a solution.But if the animated image displayed more than one time that will cause repetitive decoding operation,or the animated image’s size is too small to notice it,those cases will cause consuming unnecessary CPU’s resources.We need to find a balance between CPU usage and memory usage.

After a lot of tests(e.g.,cache part of those images,using swap-buffer),I think “cache or nothing” is a better solution.We set a parameter MemoryLimit,if the memory usage is greater than this number,we don’t cache,esle we cache.

Handle cpu usage issue.This is simple,put every operation into another thread as more as you can including the decoding operation,and execute those operation before displaying CGImage on the screen.That will have a better performance on the main thread CPU usage.

Feedback

If you have any questions,please contact me

  • @ email:wangjwchn@yahoo.com
  • @ github