GIF image creation in Go


I would like to share with you a straightforward and elegant way of creating GIF images in Go programming language. Many developers are afraid of images creation or manipulation. However, how I will present you shortly, generation of GIF images using out-of-the-box Go libraries is just fun.

Basic GIF image

In order to create a GIF image we need packages such as image, image/color and image/gif. The following function creates a GIF image with the given width and height, with the white background and a black pixel in the middle of the image. Note that for simplicity of the example I am not handling any error related to GIF encoding.

import (
  "image"
  "image/color"
  "image/gif"
)

// CreateBasicGif creates a GIF image with the given width and height.
// It uses white background and a black pixel in the middle of the image.
func CreateBasicGif(out io.Writer, width, height int) {

  palette := []color.Color{color.White, color.Black}
  rect := image.Rect(0, 0, width, height)
  img := image.NewPaletted(rect, palette)

  img.SetColorIndex(width/2, height/2, 1)

  anim := gif.GIF{Delay: []int{0}, Image: []*image.Paletted{img}}

  gif.EncodeAll(out, &anim)
}

Saving generated image

So a GIF image creation was pretty easy. A few lines of code and we have a GIF image ready. Now we need to save it. And the fascinating thing is that you can call that function with multiple io.Writer to achieve different saving methods, e.g. save the image directly to a file, to the output stream or a web request response.

This example shows the primary method of saving an image directly to a file.

import "os"

func main() {
  f, err := os.Create("my-image.gif")
  if err != nil {
    panic(err)
  }
  defer f.Close()

  CreateBasicGif(f, 50, 50)
}

This example sends an image to the output stream. You will be able to save a generated image by streaming output of your program to a file like app > image.gif.

import "os"

func main() {
  CreateBasicGif(os.Stdout, 50, 50)
}

More “advanced” GIF image

In this example, I create several images with grey colour shades palette and randomly set pixels. This example is pretty trivial and its primary purpose to give you an idea of image creation. I would encourage you to experiment with different algorithms resulting in exciting designs.

Note that I am using math/rand.Seed function to initialise random number generator with the current time in the main function.

package main

import (
  "image"
  "image/color"
  "image/gif"
  "io"
  "math/rand"
  "os"
  "time"
)

func main() {
  rand.Seed(time.Now().UnixNano())
  CreateGif(os.Stdout, 300, 100, 2, 500000)
}

// CreateGif creates a GIF image with the given width and height, number of colors and
// number of randomly set pixels. The image is written to the given out writer.
func CreateGif(out io.Writer, width, height, colors, dots int) {
  var palette = []color.Color{}

  for i, delta := 0, 255/(colors-1); i < 256; i++ {
    palette = append(palette, color.Gray{uint8(delta * i)})
  }

  rect := image.Rect(0, 0, width, height)
  img := image.NewPaletted(rect, palette)

  for i := 0; i < dots; i++ {
    x := rand.Intn(width)
    y := rand.Intn(height)
    c := rand.Intn(colors)

    img.SetColorIndex(x, y, uint8(c))
  }

  anim := gif.GIF{Delay: []int{0}, Image: []*image.Paletted{img}}

  gif.EncodeAll(out, &anim)
}

GIF images with randomly set pixels

images/scale-100x100c2.gifimages/scale-100x100c50.gif
100 x 100 pixel images with 2 (black and white) and 50 gray shades respectively - zoomed in 3 times

Conclusion

As you can see from the above examples, GIF image creation is not that scary after all. I would encourage you to visit Go documentation and review different methods related to GIF as well as other image formats.

Happy Coding!


Tags:

#color #gif #go #image #random


You may also be interested in:



comments powered by Disqus