Learning Golang (some rough notes) - S01E08 - Images

Published by in Go, Golang, Images at https://rmoff.net/2020/07/02/learning-golang-some-rough-notes-s01e08-images/

This is based on the Picture generator from the Slices exercise.

func Pic(dx, dy int) [][]uint8 {
	p := make([][]uint8,dy)
	
	for i := range p {
		p[i] = make([]uint8,dx)
	}

	 for y := range p {
        for x := range p[y] {
            p[y][x]=(uint8(x)*uint8(y))
        }
    }

	return p
}
slice02

this time it will return an implementation of image.Image instead of a slice of data.

So we need to implement the interfaces defined:

  • ColorModel

  • Bounds

  • At

Let’s start off with one of these to see if we’re on the right lines…

package main

import (
	"image/color"
	"golang.org/x/tour/pic"
)

type Image struct{}

func (i Image) ColorModel() color.Model {
	return color.RGBAModel
}

func main() {
	m := Image{}
	pic.ShowImage(m)
}

This compiles (🙌) and fails (as we’d expect) with something that may or may not be validating that we’ve not screwed things up yet:

./prog.go:17:15: cannot use m (type Image) as type image.Image in argument to pic.ShowImage:
	Image does not implement image.Image (missing At method)

Let’s add in the other fixed value, Bounds:

package main

import (
	"image"
	"image/color"
	"golang.org/x/tour/pic"
)

type Image struct{}

func (i Image) ColorModel() color.Model {
	return color.RGBAModel
}

func (i Image) Bounds() image.Rectangle {
	return image.Rect(0, 0, 256, 256)
}

func main() {
	m := Image{}
	pic.ShowImage(m)
}

Now the final part - At. Building it up bit by bit, we know what the function definition should look like, based on the above pattern and the interface definition:

func (i Image) At(x,y int) color.Color {

The value returned by this function is the colour (yes, I said colo_u_r! 🇬🇧) at the given coordinates. In the picture we created earlier this was using the expression x*y to describe the strength of the bluescale to plot. The Color type for the RGBAModel we’re using is + RGBA, which returns RGB plus alpha, so let’s try this here:

package main

import (
	"image"
	"image/color"
	"golang.org/x/tour/pic"
)

type Image struct{}

func (i Image) ColorModel() color.Model {
	return color.RGBAModel
}

func (i Image) Bounds() image.Rectangle {
	return image.Rect(0, 0, 256, 256)
}

func (i Image) At(x,y int) color.Color {
    var r,g,b,a uint8 = 25 ,0,0,0
    b=uint8(x)*uint8(y)
	return color.RGBA{r,g,b,a}
}

func main() {
	m := Image{}
	pic.ShowImage(m)
}

This not only compiles (🙌) but successfully runs (😅)…but doesn’t display anything 😢 … or does it? 🤔

In the Go execution window the Program exited is lower down the page:

image01

and if you right-click over the blank space you can see there’s an image there, and inspecting this with developer tools shows it’s a 256x256 transparent image. That alpha thingy… setting it to zero means the image is transparent!

Let’s try again and set the alpha level this time:

package main

import (
	"image"
	"image/color"
	"golang.org/x/tour/pic"
)

type Image struct{}

func (i Image) ColorModel() color.Model {
	return color.RGBAModel
}

func (i Image) Bounds() image.Rectangle {
	return image.Rect(0, 0, 256, 256)
}

func (i Image) At(x,y int) color.Color {
    var r,g,b,a uint8 = 0 ,0,0,0
    b=uint8(x)*uint8(y)
	a=b
	return color.RGBA{r,g,b,a}
}

func main() {
	m := Image{}
	pic.ShowImage(m)
}

🎉 TADA! 🎉

image02

You can muck about with the other colour values too:

func (i Image) At(x,y int) color.Color {
    var r,g,b,a uint8 = 0 ,0,0,0
	b=uint8(float64(y)*0.2) * uint8(x)
	r=uint8(float64(y)*0.5)
	a=b
	
	return color.RGBA{r,g,b,a}
}
image03
func (i Image) At(x,y int) color.Color {
    var r,g,b,a uint8 = 0 ,0,0,0
	b=uint8(float64(y)*4.25) * uint8(x*2) 
	r=uint8(float64(y)*16)
	a=b
	
	return color.RGBA{r,g,b,a}
}
image04

TABLE OF CONTENTS
OSZAR »