Julia Community 🟣

Cover image for Release of GIFImages.jl for making GIF files more accessible: GSOC'22 Work Product
Ashwani Rathee
Ashwani Rathee

Posted on

Release of GIFImages.jl for making GIF files more accessible: GSOC'22 Work Product

In this post, we discuss GIF file format and the launch of GIFImages.jl to work with GIF files in Julia.

Introduction

Graphics Interchange Format (GIF) is a bitmap image format and is very widely used due to widespread support and portability between applications and operating systems.

Important: GIF format supports up to 1 byte per pixel for each image, allowing a single image to reference its palette of up to 256 different colors chosen from the 24-bit RGB color space.

GIFs also support animations and allow a separate palette of up to 256 colors for each frame. Palette limitations make it unsuitable for images with a huge number of unique colors. GIF images are compressed using the Lempel–Ziv–Welch (LZW) lossless data compression technique to reduce the file size without degrading the visual quality.

Let's take the example of Chelsea to understand GIFs.

Chelsea Animation

GIFImages.jl provides support for methods to decode(read) and encode(write to gif from single/multiple image array) to GIF files.

julia> using GIFImages
julia> filepath = "chelsea-disappears.gif"
julia> imgs = gif_decode(filepath)
300×451×7 Array{RGB{N0f8},3} with eltype RGB{N0f8}:
[:, :, 1] =
 RGB{N0f8}(0.635,0.494,0.404)  RGB{N0f8}(0.635,0.494,0.404)  …  RGB{N0f8}(0.176,0.102,0.051)
 RGB{N0f8}(0.663,0.525,0.447)  RGB{N0f8}(0.663,0.525,0.447)     RGB{N0f8}(0.2,0.122,0.067)
 ⋮                                                           ⋱  ⋮

 RGB{N0f8}(0.549,0.392,0.275)  RGB{N0f8}(0.506,0.341,0.212)     RGB{N0f8}(0.635,0.494,0.404)

[:, :, 2] =
:
:
Enter fullscreen mode Exit fullscreen mode

The size of the returned image is (300,451,7) which represents the height, width, and number of images respectively. GIF images are RGB palette based and 256 different colors can be chosen from the 24-bit RGB color space. Now, let's how we made this GIF with gif_encode

julia> using GIFImages, TestImages
julia> chel = testimage("chelsea") 
julia> gif_arr = ones(RGB{N0f8}, (size(chel)[1], size(chel)[2], 7)) #gif image array
julia> map(x->gif_arr[:,:,x]=chel, [1,2,3,4,5,7])
julia> map(x->gif_arr[:,1:x*100,x+1] .= RGB{N0f8}.(1.0,1.0,1.0) , 1:4) # covering more and area with white color in subsequent images.
julia> gif_encode("chelsea-disppears.gif", gif_arr)

Enter fullscreen mode Exit fullscreen mode

And now take another tiny gif_image of size(2,2,6) to understand the file structure:

Tiny GIF

That tiny black dot is 4(2x2) pixels of your computer screen!! Now let's see GIF image file structure and understand with help of our new GIF:

GIF file format

How gif under lens looks like:

GIF under lens! Appearance
Tiny GIF view Enlarged View

Now, let's see how data is organized in our small gif!!

GIF structure

Data is highlighted to differentiate different sections in the gif file.

  • Header block: First 6 bytes(Yellow)
  • Logical Screen Descriptor: Next 7 bytes
  • Global Color Table: Next 6 bytes(Purple)

Now for each image, starts with 0x2C:

  • Image Descriptor: 9 bytes(Purple)
  • Image Compressed data afterwards(Mint Green)

In end, file ends with 0x3B

The Why

One might ask why use GIFImages instead of already existing ImageMagick method which is provided by FileIO load, save.
Why then?

  • Decoding process time taken is much faster(x15 times), encoding process time taken is comparable(work in progress).
  • GIFImages allows support for using local colormaps for decoding GIF which has made a big difference in decoding, I have noticed less erroneous decoding with support for using both local and global color palettes.
  • Encoding method provides a way to limit number of colors to a certain number which ImageMagick approach doesn't.

Note!!!!

GIFImages.jl is now available for the community's use in Julia's General Registry and can be simply installed using:

# Enter ']' from the REPL to enter Pkg mode.
pkg> add GIFImages
Enter fullscreen mode Exit fullscreen mode

Future Work

  • Work on support for the application extension block which allows to create animations in the gif file and allow looping.
  • Add GIFImages support to ImageIO which JuliaImages wants to use to deprecate the old ImageMagick backend with faster IO support.
  • Improve upon the color quantization methods that were written to support the encoding process of GIFs, mainly memory allocations are concerning.
  • In the distant future, consider and if needed provide in-house support for GIFs by writing GIF support in Julia itself, rather than relying on LibGif

Acknowledgments

Thank you @johnnychen94 for being constant support as a mentor and a friend over the years!!

References:

Top comments (2)

Collapse
 
Sloan, the sloth mascot
Comment deleted
Collapse
 
fabiorsodre profile image
Fábio Sodré

Wonderful work