Recently i incorporated support for creating thumbnails in glgif, the backend gif animation library used in Anim8gif.
Rather than taking the easy route out and attempting to load the gif using UIImage, i decided to take advantage of glgif’s decode routines to create an accurate representation of the current state of the gif playback.
Put simply, i took the palette texture which is generated for display, and decoded it into a new UIImage.
The actual process is triggered by assigning a delegate (thumbDelegate), which will be invoked when the next frame in the gif is decoded. The delegate is then cleared.
Simple, right?
More Technical Details
The format of a palette texture in GLES is as follows:
| Palette (16 or 256 entries) | Indexed Pixels (4bit or 8bit) |
The palette can either be 16 or 256 entries long, depending on the format you use. Likewise the pixel data will either use 4 bits or 8 bits. To keep things simple, glgif uses an 8bit palette with 3 8bit entries for the color (GL_PALETTE8_RGB8_OES).
(Note that an 8bit palette can be insufficient as a gif can actually display more than 256 colours across multiple frames, but this is a necessary trade-off for speed)
So in order to decode it:
- Read and decode the palette
- Decode each pixel as an index into the palette
- Using the decoded pixel data, create a new CoreGraphics bitmap context (using CGBitmapContextCreate)
- Convert the bitmap context into a UIImage (using CGBitmapContextCreateImage and [UIImage imageWithCGImage:])
The resultant UIImage can then easily be used as a base to generate a sized down thumbnail of the gif, as illustrated below.
As always, the code for glgif is hosted on github, so feel free to check it out!