Golang: Creating Images and Drawing — Simply Explained (Part 1)

Photo by Eddy Klaus on Unsplash

Understanding the key elements of the framework

Interface image.Image

  1. Function that returns a color model — this color model is how the data translating to pixels are stored in binary format;
  2. Function that returns the bounding rectangle — this represents the size of the rectangle that forms the bounding geometry of the image; and
  3. Function that returns the color.Color at the input x and y integer coordinates.
type Image interface {

ColorModel() color.Model

Bounds() Rectangle

At(x, y int) color.Color

Interface draw.Image

type Image interface {
Set(x, y int, c color.Color)

Actual Structs

  • Gray —8-bit greyscale
  • Gray16– 16–bit greyscale
  • CMYK
  • Paletted
  • RGBA — most commonly know color model of red, green, blue and alpha channels, each 8 bits
  • NRGBA — non-alpha-premultiplied 32-bit color (each channel is 8-bit)
  • NRGBA64 — non-alpha-premultiplied 64-bit color (each channel is 16-bit)
  • NYCbCrA — non-alpha-premultiplied Y’CbCr-with-alpha (8-bit for each of Luma and the two chroma components; JPEG, VP8, MPEG codecs etc use this color model)
  • Alpha — a single channel (alpha) 8-bit
  • Alpha16 — a single channel (alpha) 16-bit

Now that I know about the structs, but how do you get the structs then?

import _ "image/jpeg" //will call the init() function of the package
//thus enabling working with jpeg file
func OpenImage(path string) (image.Image, error) {
f, err := os.Open(path)
if err != nil {
return nil, err
defer f.Close()
img, format, err := image.Decode(f)
if err != nil {
e := fmt.Errorf("error in decoding: %w", err)
return nil, e
if format != "jpeg" && format != "png" {
e := fmt.Errorf("error in image format - not jpeg")
return nil, e
return img, nil
func GetImageTensor(img image.Image) (pixels [][]color.Color) {
size := img.Bounds().Size()
for i := 0; i < size.X; i++ {
var y []color.Color
for j := 0; j < size.Y; j++ {
y = append(y, img.At(i, j))
pixels = append(pixels, y) // 2 by 2 slices where
//each contains a color.color
func ConvertGreyScale(pixels *[][]color.Color) image.Image {        p := *pixels
wg := sync.WaitGroup{}
rect := image.Rect(0, 0, len(p), len(p[0]))
newImage := image.NewRGBA(rect)
for x := 0; x < len(p); x++ {
for y := 0; y < len(p[0]); y++ {
go func(x, y int) {
pix := p[x][y]
originalColor, ok := color.RGBAModel.Convert(pix).(color.RGBA)
if !ok {
log.Fatalf("color.color conversion went wrong")
grey := uint8(float64(originalColor.R)*0.21 + float64(originalColor.G)*0.72 + float64(originalColor.B)*0.07)
col := color.RGBA{
newImage.Set(x, y, col)
}(x, y)
return newImage
Original image (courtesy of CC) and the grayscaled image
Example of the draw library where you can place your own QR code through compositing




Writing to soothe the soul, programming to achieve flow

Love podcasts or audiobooks? Learn on the go with our new app.

Recommended from Medium

Begin Your Adventures with DoragonLand Mobile Test Version on Android!

Unity and Object movement

Add a soft ui design to your site (neumorphism)

credit: https://www.pinterest.com/pin/455074737350700472/

Learn Python in a Hurry if You Know C#

Architecture Cassandra,Best Practices, Installation Cluster Multi DC With Ansible

Flutter Dart Documentation

Create & issue your own token on the Ethereum or BSC Network with GraphLinq

Configure Hadoop Using Ansible Playbook

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store


Writing to soothe the soul, programming to achieve flow

More from Medium

FIFO in Queue Collection.!!!

Rate-limiting with Token Buckets

Deploying the JDA discord bot with Docker

Role Based Access(RBAC) Part IV : MongoDB via Atlas