FAQ
I have this code working and have been playing around with various
functions. Thought I would add random noise to the image. No matter what I
do, does not seem to work. Any insight would be appreciated

-- I am more concerned with my inability to understand how to cast to the
correct type and not whether or not I can add random noise to the tutorial
picture.

Thanks for any thoughts.

//Code is below
package main

import (
"tour/pic"
//"fmt" //for debug
"math/rand"
)

func Pic(dx, dy int) [][]uint8 {
image := make([][]uint8,dy)
for y := 0; y < dy; y++ {
image[y] = make([]uint8,dx)
for x := 0; x < dx; x++ {
v := uint8(rand.Float32() * 128.0)
//fmt.Print(v, " ") //for debug.
image[y][x] = v
}
fmt.Println()
}
return image
}

func main() {
pic.Show(Pic)
}

--

Search Discussions

  • Si guy at Nov 22, 2012 at 8:26 am
    The output of Pic appears to be truncated on the go tour. Probably some
    sort of memory limit.

    --
  • Matthew Alan Martin at Nov 22, 2012 at 6:48 pm
    Thanks for the thought. If you set the value to a constant or a function of
    x, y, the code does in fact produce an output image. The array is already
    allocated, so no memory problem there. I would be hard pressed to think
    that "math/rand" takes up more memory than "math" - for example if you plot
    a function of math.Pow(), so I don't think it is a package size problem.

    I guess if no one sees a type-casting problem in my code it must just be
    that the packages you can load are restricted in the tutorials.
    On Thursday, November 22, 2012 2:26:40 AM UTC-6, si guy wrote:

    The output of Pic appears to be truncated on the go tour. Probably some
    sort of memory limit.
    --
  • Nigel Tao at Nov 23, 2012 at 3:34 am

    On Fri, Nov 23, 2012 at 5:47 AM, wrote:
    Thanks for the thought. If you set the value to a constant or a function of
    x, y, the code does in fact produce an output image. The array is already
    allocated, so no memory problem there.
    Memory isn't the issue. The total length of a tour.golang.org
    program's output is capped. By setting every pixel to a random value,
    the encoded image is relatively large, as random noise doesn't
    compress very well. By setting only a portion of the image to random
    noise, you get under the cap. For example, the program below should
    work on http://tour.golang.org/#47

    --------
    package main

    import (
    "math/rand"
    "tour/pic"
    )

    func Pic(dx, dy int) [][]uint8 {
    image := make([][]uint8, dy)
    for y := 0; y < dy; y++ {
    image[y] = make([]uint8, dx)
    for x := 0; x < dx; x++ {
    v := uint8(rand.Float32() * 128.0)
    if x > 60 {
    v = uint8(y)
    }
    image[y][x] = v
    }
    }
    return image
    }

    func main() {
    pic.Show(Pic)
    }
    --------

    --
  • Matthew Alan Martin at Nov 23, 2012 at 12:48 pm
    Thanks Nigel. Nice to know I am not totally off base here.
    On Thursday, November 22, 2012 9:34:18 PM UTC-6, Nigel Tao wrote:

    On Fri, Nov 23, 2012 at 5:47 AM, <matthew.a...@gmail.com <javascript:>>
    wrote:
    Thanks for the thought. If you set the value to a constant or a function of
    x, y, the code does in fact produce an output image. The array is already
    allocated, so no memory problem there.
    Memory isn't the issue. The total length of a tour.golang.org
    program's output is capped. By setting every pixel to a random value,
    the encoded image is relatively large, as random noise doesn't
    compress very well. By setting only a portion of the image to random
    noise, you get under the cap. For example, the program below should
    work on http://tour.golang.org/#47

    --------
    package main

    import (
    "math/rand"
    "tour/pic"
    )

    func Pic(dx, dy int) [][]uint8 {
    image := make([][]uint8, dy)
    for y := 0; y < dy; y++ {
    image[y] = make([]uint8, dx)
    for x := 0; x < dx; x++ {
    v := uint8(rand.Float32() * 128.0)
    if x > 60 {
    v = uint8(y)
    }
    image[y][x] = v
    }
    }
    return image
    }

    func main() {
    pic.Show(Pic)
    }
    --------
    --
  • Gorky Park at Nov 23, 2012 at 10:41 am
    Btw, is there a saner way of addressing [256][256]uint8 as [][]uint8 than
    this? Seems terribly inefficient and ugly to use ias as intermediate.

    package main

    import "tour/pic"

    func Pic(dx, dy int) [][]uint8 {
    var ia = new([256][256]uint8)
    for i,j := range ia {
    for l,_ := range j {
    ia[i][l] = uint8(i+l)
    }
    }
    var ias [256][]uint8 //array of slices
    for i:= range ia { ias[i] = ia[i][:] }
    var iss [][]uint8 //slice of slices
    iss = ias[:]
    return iss
    }

    func main() {
    pic.Show(Pic)
    }

    --
  • Matthew Alan Martin at Nov 23, 2012 at 12:48 pm
    Thanks! This explains it.

    As far as a more elegant way, I did not know one could pre-allocate the 2
    dims with 'new' as you have shown, particularly because the notes for 47
    say that "(You need to use a loop to allocate each []uint8 inside the
    [][]uint8.)".
    I also did not know one could allocate slices in that way since the
    tutorial on slices says: "Slices are created with the 'make' function. It
    works by allocating a zeroed array and returning a slice that refers to
    that array:", and not 'new'

    Lots to learn here. Thanks for you help.
    On Friday, November 23, 2012 4:41:38 AM UTC-6, Gorky Park wrote:

    Btw, is there a saner way of addressing [256][256]uint8 as [][]uint8 than
    this? Seems terribly inefficient and ugly to use ias as intermediate.

    package main

    import "tour/pic"

    func Pic(dx, dy int) [][]uint8 {
    var ia = new([256][256]uint8)
    for i,j := range ia {
    for l,_ := range j {
    ia[i][l] = uint8(i+l)
    }
    }
    var ias [256][]uint8 //array of slices
    for i:= range ia { ias[i] = ia[i][:] }
    var iss [][]uint8 //slice of slices
    iss = ias[:]
    return iss
    }

    func main() {
    pic.Show(Pic)
    }
    --
  • Gorky Park at Nov 23, 2012 at 3:29 pm

    On Friday, November 23, 2012 7:48:17 PM UTC+7, matthew.a...@gmail.com wrote:
    Lots to learn here. Thanks for you help.
    My code is not an exact answer to #47 because the premise is you allocate
    the memory dynamically (use loop counters based on dx & dy).

    It was more like an alternate version, how to do it with a fixed array.
    Those temp arrays for creating slices get uglier the more dimensions an
    array has. Wish one could cast slice[][][] = array[x][y][z] in one
    command, that would be neat and clean.

    --
  • Nigel Tao at Nov 24, 2012 at 12:26 am

    On Fri, Nov 23, 2012 at 9:41 PM, Gorky Park wrote:
    Btw, is there a saner way of addressing [256][256]uint8 as [][]uint8 than
    this? Seems terribly inefficient and ugly to use ias as intermediate.
    --
  • Nigel Tao at Nov 24, 2012 at 12:33 am
    Whoops, I accidentally hit "send"...
    On Fri, Nov 23, 2012 at 9:41 PM, Gorky Park wrote:
    Btw, is there a saner way of addressing [256][256]uint8 as [][]uint8 than
    this? Seems terribly inefficient and ugly to use ias as intermediate.
    Using a [256][256]uint8 reminds me of the joke where a patient tells a
    doctor "it hurts when I do that", and the doctor says "don't do that".

    I would write it like this:

    func Pic(dx, dy int) [][]uint8 {
    m := make([][]uint8, dy)
    for y := range m {
    m[y] = make([]uint8, dx)
    for x := range m[y] {
    m[y][x] = uint8(x * y)
    }
    }
    return m
    }

    If you would rather make one big []uint8 allocation instead of many
    smaller []uint8 allocations, I would write:

    func Pic(dx, dy int) [][]uint8 {
    m := make([][]uint8, dy)
    buf := make([]uint8, dy*dx)
    for y := range m {
    m[y] = buf[y*dx : (y+1)*dx]
    for x := range m[y] {
    m[y][x] = uint8(x * y)
    }
    }
    return m
    }

    --

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
groupgolang-nuts @
categoriesgo
postedNov 22, '12 at 5:24a
activeNov 24, '12 at 12:33a
posts10
users4
websitegolang.org

People

Translate

site design / logo © 2022 Grokbase