HiveBrain v1.2.0
Get Started
← Back to all entries
patterngoMinor

"Images" exercise from A Tour of Go

Submitted by: @import:stackexchange-codereview··
0
Viewed 0 times
imagesfromtourexercise

Problem

The "Images" exercise in A Tour of Go asks for an implementation of image.Image. I wrote two solutions, one easy and one harder (just for practice in dealing with interfaces).

SOLUTION 1: (HARD WAY)

package main

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

type Image struct{
    // one array for x value, one array for y values, array of integer for pixel RGBA values
    image_ [][][]uint8
    x0, y0, x1, y1 int
}

func (i *Image) NewImage(x, y int) *Image {
    image := make([][][]uint8, y)
    for i := 0; i < x; i++ {
        image[i] = make([][]uint8, x)
        for j := 0; j < y; j++ {
            image[i][j] = make([]uint8, 4)
        }
    }
    return &Image{image, 0, 0, x, y}
}

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

func (p *Image) At(x, y int) color.Color {
    var c color.Color
    rgba := color.RGBA{
        p.image_[x][y][0],
        p.image_[x][y][1],
        p.image_[x][y][2],
        p.image_[x][y][3],
    }
    c = rgba
    return c
}

func (p *Image) Bounds() image.Rectangle {
    rectangle := image.Rect(p.x0, p.y0, p.x1, p.y1)
    return rectangle
}

func (p *Image) crazyColors() *Image {
    for i := 0; i < len(p.image_) - 1; i++ {
        for j := 0; j < len(p.image_[i]) - 1; j++ {
            p.image_[i][j][0] = uint8(i + j / 2)
            p.image_[i][j][1] = uint8(i + j * 2)
            p.image_[i][j][2] = uint8(i + j * 2)
            p.image_[i][j][3] = uint8(255)
        }
    }
    return p
}

func main() {
    var i *Image
    i = i.NewImage(255, 255)
    i.crazyColors()
    pic.ShowImage(i)
}


SOLUTION 2: (EASY WAY)

```
package main

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

type Image struct{
image.RGBA
}

func (i Image) crazyColors() Image {
for p := 0; p < len(i.Pix); p += 4 {
i.Pix[p] = uint8(p + p*2)
i.Pix[p+1] = uint8(p + p*2)
i.Pix[p+2] = uint8(p + p*2)
i.Pix[p+3] = uint8(p + p*2)
}
return i
}

func main()

Solution

Storing a rectangle

The Image stores the parameters to create a rectangle. Those values are not used for anything else in the lifetime of the object, except to create the bounding rectangle when needed. You could instead just store the rectangle itself, so could simply return it when needed.

Pointless local variables

Many of the local variables are pointless, you could skip declaring and assigning to them and simply return values directly, for example:

func (p *Image) At(x, y int) color.Color {
    return color.RGBA{
        p.image_[x][y][0],
        p.image_[x][y][1],
        p.image_[x][y][2],
        p.image_[x][y][3],
    }
}


Naming

The _ suffix in Image.image_ is unusual. I suggest to simply drop the suffix.

The name i is most often used in simple counting loops, I suggest to avoid using it for other purposes. A good short name for an image instance could be img, for example.

Code Snippets

func (p *Image) At(x, y int) color.Color {
    return color.RGBA{
        p.image_[x][y][0],
        p.image_[x][y][1],
        p.image_[x][y][2],
        p.image_[x][y][3],
    }
}

Context

StackExchange Code Review Q#144012, answer score: 2

Revisions (0)

No revisions yet.