GoLang Image Processing

Image Processing Golang

Are you GOing somewhere? Welcome to another Go article, where we’ll look at what we can do with images in Go. We will learn how to create an image, import, and export images. We will also learn the basics of image processing in Go. Today I will be coding again on VS Code. So let’s get started.

Create an image matrix using image package

For a short background on images and color:

  • An image is made of pixels
  • All pixels are values ranging from 0-255
  • There are various color formats, though RGBA is most popular across all systems
  • RGBA stands for Red, Green and Blue values.

We can create an image matrix using image.NewRGBA():

package main

import (
	"image"
)
func main() {
	myImg := image.NewRGBA(image.Rect(0, 0, 12, 6))
        ...
}

We can access the pixel matrix (or rather Go array) using myImg.Pix[0] for 1st pixel, myImg.Pix[1] for 2nd pixel, and so on.

Importing an image using os package

We can easily import an image using os.Open() and then decoding that using image.Decode():

package main

import (
	"fmt"
	"image"
	"image/png"
	"log"
	"os"
)

func main() {
	catFile, err := os.Open("/home/arkaprabham/Documents/Journal_Dev/Golang/github.com/image-op/cat.png")
	if err != nil {
		log.Fatal(err)
	}
	defer catFile.Close()

	imData, imType, err := image.Decode(catFile)
	if err != nil {
		fmt.Println(err)
	}

	fmt.Println(imData)
	fmt.Println(imType)

	cat, err := png.Decode(catFile)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println(cat)
}

ImData Output
ImData Output

Exporting an image to file

Now that we know how to import an image, we should also learn how to save an image to a file. Let’s save the empty image matrix we created earlier:

package main

import (
	"image"
)
func main() {
	myImg := image.NewRGBA(image.Rect(0, 0, 12, 6))
        out, err := os.Create("cat.png")
        png.Encode(out, myImg)
        out.Close()
}
Saved Image File
Saved Image File

Important subdirectories in the image library are:

  • color – color implements a basic color library.
  • palette – palette provides standard color palettes.
  • draw – draw provides image composition functions.
  • gif – gif implements a GIF image decoder and encoder.
  • jpeg – jpeg implements a JPEG image decoder and encoder.
  • png – png implements a PNG image decoder and encoder.

So we’ll dive into the png library, and the rest are just similar implementations for various formats.

PNG image Package

GoLang png package implements a PNG image decoder and encoder. A wonderful implementation of converting an image from base64 string to png, and then printing it with 5 levels of lines:

package main

import (
	"fmt"
	"image/color"
	"image/png"
	"log"
	"os"
)

func main() {
	// This example uses png.Decode which can only decode PNG images.
	catFile, err := os.Open("/home/arkaprabham/Documents/Journal_Dev/Golang/github.com/image-op/cat.png")
	if err != nil {
		log.Fatal(err)
	}
	defer catFile.Close()

	// Consider using the general image.Decode as it can sniff and decode any registered image format.
	img, err := png.Decode(catFile)
	if err != nil {
		log.Fatal(err)
	}

	fmt.Println(img)

	levels := []string{" ", "░", "▒", "▓", "█"}

	for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y++ {
		for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x++ {
			c := color.GrayModel.Convert(img.At(x, y)).(color.Gray)
			level := c.Y / 51 // 51 * 5 = 255
			if level == 5 {
				level--
			}
			fmt.Print(levels[level])
		}
		fmt.Print("\n")
	}
}

First we open the png image file of a cat (get any picture from the internet), and then pass it in png.Decode().

Then we define the different strings and use a for loop to go through all the pixels and replace it with one of the level strings. The output is fairly recognisable:

3 Cats Image In Terminal
3 Cats Image In Terminal

Ending Notes

We require these basics for any further operations to perform on images such as blurring or isolating color channels. The most important resources are the image package. Once that is done, you may want to go over an awesome collection of Go packages for advanced image operations.