DEV Community

Robin Moffatt
Robin Moffatt

Posted on • Originally published at rmoff.net on

Learning Golang (some rough notes) - S01E08 - Images

👉 A Tour of Go : Exercise: 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
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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)
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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 {
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

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)
}
Enter fullscreen mode Exit fullscreen mode

🎉 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}
}
Enter fullscreen mode Exit fullscreen mode

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}
}
Enter fullscreen mode Exit fullscreen mode

image04

Top comments (0)