duansaxf095988 2016-08-20 02:27
浏览 24
已采纳

Golang练习片如何处理大价值

I'm going through the Golang tutorial and I'm a little bit confused as to what it is doing with some of the values in the slices exercise. https://tour.golang.org/moretypes/18

Here is the code that I am confused with:

A value of 0 is a perfectly blue pixel and a value of 255 is a perfectly white pixel. So what is happening here when the value displayed is some form of x*y (I did /20 to make the image a little bit bigger and easier to see).

If you follow the image horizontally, you will see that at some point in the process, the ever increasing x and y values seem to revert to blue (0 value) If I type a static value like 256 in the return I get a compile error. So it obviously does not allow the numbers to go off the scale and revert to 0 or anything. So how does it get the blue curves in the picture?

imported source here: https://github.com/golang/tour/blob/master/pic/pic.go#L15

package main

import "golang.org/x/tour/pic"

func Pic(dx, dy int) [][]uint8 {
    //First, the array has to be made so we can put some values in it later
    //This only makes the second dimension of the array ([[uint8 dy]])?
    image := make([][]uint8, dy)

    //The inputs into the function are Int's, so it is ok to have a non uint8
    //loop initializer
    for x := 0; x < dy; x++ {
        //once we are in the loop we have to make the first dimension of the array
        //based on the dx values
        image[x] = make([]uint8, dx)
        for y := 0; y < dx; y++ {
            //This is a function +to assign the pixel values to the array
            image[x][y] = uint8((x * y) /20)
        }
    }
    return image
}

func main() {
    pic.Show(Pic)
}
  • 写回答

2条回答 默认 最新

  • duanlu9970 2016-08-20 04:29
    关注

    Imagine i is of type int, uint8(i) returns Least Significant Byte (LSB) of i:

    When x is in range [0, 255] , meaning: 0 <= x <= 255
    and y is in range [0, 255],
    then x*y is in range [0, 255*255] = [0, 65025]
    so x*y/20 is in range [0, 255*255/20] = [0, 65025/20] = [0, 3251]
    and value of uint8(x*y/20) is equal to (x*y/20)%256 meaning exactly LSB byte:
    uint8(3251) = uint8(0XCB3) = 0XB3 = 179
    3251 = 12*256 + 179

    So every time the x*y/20 is bigger than 255 it counts from 0 again: (x*y/20) % 256 this is why your image is repeated circles.

    Try this working sample code:

    package main
    
    import "fmt"
    
    func main() {
        for y := 0; y <= 255; y++ {
            for x := 0; x <= 255; x++ {
                v := x * y / 20
                if int(uint8(v)) != v%256 {
                    fmt.Println(v, v%256)
                }
            }
        }
        fmt.Println("Done.")
    }
    

    output:

    Done.
    

    Let's simplify you example, see this working sample code:

    package main
    
    import (
        "bytes"
        "image"
        "image/png"
        "os"
    )
    
    func main() {
        const dx = 256
        const dy = 256
        m := image.NewNRGBA(image.Rect(0, 0, dx, dy))
        for y := 0; y < dy; y++ {
            for x := 0; x < dx; x++ {
                v := uint8(x * y / 20)
                i := y*m.Stride + x*4
                m.Pix[i] = v     //R
                m.Pix[i+1] = v   //G
                m.Pix[i+2] = 255 //B
                m.Pix[i+3] = 255 //A
            }
        }
        var buf bytes.Buffer
        err := png.Encode(&buf, m)
        if err != nil {
            panic(err)
        }
        os.Stdout.Write(buf.Bytes())
    }
    

    And redirect the output to a file like main > b.png or, go run main.go > b.png
    see output file b.png:
    enter image description here

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害
  • ¥15 华为ensp模拟器中S5700交换机在配置过程中老是反复重启
  • ¥15 java写代码遇到问题,求帮助
  • ¥15 uniapp uview http 如何实现统一的请求异常信息提示?
  • ¥15 有了解d3和topogram.js库的吗?有偿请教
  • ¥100 任意维数的K均值聚类
  • ¥15 stamps做sbas-insar,时序沉降图怎么画
  • ¥15 买了个传感器,根据商家发的代码和步骤使用但是代码报错了不会改,有没有人可以看看