Category: Blog, Android, Business, Development

GIF App Development – Challenges & Tips

Do you want to develop an app like Giphy Cam? Learn what challenges you can expect during your GIF app development.

GIF maker app development challenges

In this article, we’ll discuss animated GIFs creation on Android platform. If you want to develop an app like Giphy Cam or GIF Maker & GIF Editor & Video Maker, it’s worth knowing what challenges you can expect during a GIF maker app development, and how to face them.

GIF apps examples

Android GIF apps examples

Why Android does (did?) not support (animated) GIFs natively?

GIFs support on Android was never perfect since the beginning. The long story short: up to Android 8 (Oreo), the system itself (so not taking into account any third party libraries) used to support only non-animated GIFs displaying (for animated GIFs only the first frame is shown as a static image). There is no encoding support at all.

Android Pie Cumulative Distribution in June 2020

Generated by Android Studio

Starting from Android 9 (Pie), Image Decoder is available. It can produce Animated Image Drawables. Unfortunately, these classes are only part of the platform and are not backported to AndroidX Jetpack, so nowadays (June 2020), only about 40% of users can benefit from them.

Why GIF support is so complicated?

OK, but why GIF support is so poor on Android? Well, only Google can tell the truth. However, we may try to deduce some reasons…

Firstly, it is much more difficult to implement displaying an animated image, than the static one. Secondly, encoding (creating new files) is more difficult than decoding (reading and displaying). So we have a difficulty combo!

Read also article about how to develop GIF encoding in your app.

Static images vs animations

Let’s first discover differences between static images (eg. PNG or JPG), and animations (like GIF, but GIFs can also be not animated).

Static image decoding usually boils down to taking input (like local file or image URL) and producing output (bitmap – a 2-dimensional array of pixels). After that operation, everything is up to the UI layer, and the decoder does not need to care about that. Note that we’re considering the simple case now – displaying an image as is. The fully-fledged image decoding libraries like Glide or Coil have additional features like caching, transformations, etc.

Animation can be described as a sequence of static images (frames). So the decoding process consists of multiple aforementioned steps. However, there are more factors to consider. Firstly, we need some kind of a ticker (clock) which is responsible for advancing the time (switching to subsequent frames).

Such a clock needs to be aware of the UI lifecycle. Especially it needs to be disposed of when UI is no longer alive (eg. user pressed the back button or simply switched to another app).

Now, we are getting to the point. Proper handling of the Android UI lifecycle is a significant challenge for developers implementing it. A lot of bugs and crashes in Android applications are caused by leaks which are effects of improper lifecycle handling. Even Google recently deprecated AsyncTask – a class that they invented by themselves and promoted for years. The Movie class, used frequently for GIF decoding, also used to have a leak. After 2 months another one was discovered.

Encoding vs decoding

Now, let’s take a deeper look into GIF encoding and see why this process is much more complicated than decoding. There are 2 main reasons.

Image data in GIF file is divided into frames. However, they are not always the same as physical film frames. Let’s take a look at the following animation:
animation
The most efficient way of encoding is to store only differences of subsequent frames:
sample 2 animation green
sample 2 green yellow diff
Of course, nothing prohibits from saving the full-sized second frame like this:
sample 2 animation yellow
However, doing so will cause that overall GIF file size will be much bigger (and as you can read in the next paragraphs, the number of colors may be then limited).

Note, that GIF files used in real life usually contain dozens or hundreds of frames, frequently larger than one in this simple example. Usually, the source of the movie from which GIF is going to be produced outputs full-sized frames. Extracting differences between subsequent frames is not a trivial problem.

The vast majority of all currently used computer and mobile displays (probably including the one you are reading this article on), as well as image formats (GIF, JPG, PNG, etc.), use 24-bit color depth. That means about 16 million colors (the average human eye can distinguish about 10 million).

However, the single GIF frame may only contain up to 256 distinct colors. As you can remember from the previous paragraphs, the currently visible state of GIF animation may contain many frames, so the number of colors in the whole GIF is not the same as in a single frame.

So, how to pack 16 millions of possibilities into 256 places? Well, it is hard to do that efficiently, but many techniques have been developed, they are collectively called dithering. Despite that GIF format is over 30-years old (so one may think that we should know almost everything about it through and through) the new encoding techniques eg. GIFnets are constantly being developed.

GIF encoding is a complex operation, and it needs to work on Android devices with reasonable performance. Creating GIF encoding in your app requires skilled developers, who know how to use the Native Development Kit (NDK).

How to deal with obstacles in GIF app development?

As you can see, GIF maker app development for Android creates many problems. Is there any way to solve them all? Well, there is no silver bullet. However, we can find some partial solutions which can be further assembled.

Animated GIF displaying is nowadays handled by many well-known 3rd party libraries like Glide, Coil, but not Picasso. For more complex operations involving eg. rendering into OpenGL textures or changing the framerate, you may use android-gif-drawable.

However, GIF encoding on Android will often require a little bit of additional development and familiarity with NDK.

Ready-to-use libraries do exist, but may be either not-fully functional (like gifencoder not supporting transparency), or no longer maintained (like GifEncoder). Many well-known open-source low-level graphic libraries like gifsicle or FFmpeg can be compiled for Android. There are even wrappers like Mobile FFmpeg which may simplify adaptation to Android.

GIF app development – wrap-up

As you can see, it is hard to display and even much harder, to create animated GIFs. Even Google developers have trouble with that. Keep in mind:

  • GIF app development for Android requires additional time for research and testing.
  • When choosing a development team that will build your GIF maker app for Android, make sure they are familiar with Android NDK.
  • As these types of projects are not a piece of cake, it’s worth working with a team that already has experience in creating similar applications.
  • A solution recommended today, may become obsolete and deprecated tomorrow, so the app may need regular maintenance.

Check out the GIPHY Cam app developed by us.

About the author

Karol Wrótniak

Karol Wrótniak

Mobile Developer

Flutter & Android Developer with 12 years of experience. A warhorse with impressive experience and skills in native and Flutter app development. Karol is probably the most active contributor to open source libraries you've ever met. He develops Gradle plugins and Bitrise steps, and he is engaged in many projects, in particular those related to testing.

Karol has been engaged as a speaker in many events and meetups like DevFest, 4Developers Wrocław, JDD Conference, Linux Academy, and more. He is an active member of Google Developers Group Wrocław, Flutter Wrocław, and Bitrise User Group.