代码之家  ›  专栏  ›  技术社区  ›  vityavv

转到:image.at返回零

  •  0
  • vityavv  · 技术社区  · 7 年前

    我有个问题。这是我的代码:

    package main
    
    import (
        "math/rand"
        "image/draw"
        "image/png"
        "image/color"
        "strconv"
        "os"
        "time"
        "fmt"
    )
    
    func genSites(width, height int) ([][]int) {
        rand.Seed(time.Now().Unix())
        l, err := strconv.Atoi(os.Args[len(os.Args)-2])
        if err != nil {
            panic(err)
        }
        sites := make([][]int, l)
        for i := range sites {
            sites[i] = make([]int, 2)
            sites[i][0] = rand.Intn(width)
            sites[i][1] = rand.Intn(height)
        }
        return sites
    }
    
    func main() {
        inputF, err := os.Open(os.Args[len(os.Args)-3])
        if err != nil {
            panic(err)
        }
        defer inputF.Close()
    
        inputR, err := png.Decode(inputF)
        if err != nil {
            panic(err)
        }
        input := inputR.(draw.Image)
        minx, miny := input.Bounds().Min.X, input.Bounds().Min.Y
        maxx, maxy := input.Bounds().Max.X-1, input.Bounds().Max.Y-1
        sites := genSites(maxx-minx, maxy-miny)
        siteColors := make([][]color.Color, len(sites))
        //todo: figure out something better than this
        for i := range siteColors {
            siteColors[i] = make([]color.Color, (maxx-minx)*(maxy-miny))
        }
        siteBelongs := make([][]int, maxx - minx)
        for x := range siteBelongs {
            siteBelongs[x] = make([]int, maxy - miny)
            for y := range siteBelongs[x] {
                dmin := (maxx-minx)*(maxx-minx) + (maxy-miny)*(maxy-miny)
                var smin int
                for i, s := range sites {
                    d := (s[0]-x)*(s[0]-x) + (s[1]-y)*(s[1]-y)
                    if d > dmin {
                        smin = i
                        dmin = d
                    }
                }
                siteBelongs[x][y] = smin
                siteColors[smin] = append(siteColors[smin], input.At(x+minx, y+miny))
            }
        }
        siteAvgColors := make([]color.Color, len(sites))
        for i := range siteAvgColors {
            var sR, sG, sB, sA int
            for _, val := range siteColors[i] {
                fmt.Println(val)
                r, g, b, a := val.RGBA()
                sR += int(r)
                sG += int(g)
                sB += int(b)
                sA += int(a)
            }
            siteAvgColors[i] = color.RGBA{
                uint8(sR/len(siteColors[i])),
                uint8(sG/len(siteColors[i])),
                uint8(sB/len(siteColors[i])),
                uint8(sA/len(siteColors[i]))}
        }
        for x := range siteBelongs {
            for y := range siteBelongs[x] {
                input.Set(minx + x, miny + y, siteAvgColors[siteBelongs[x][y]])
            }
        }
        output, err := os.Create(os.Args[len(os.Args)-1])
        if err != nil {
            panic(err)
        }
        defer output.Close()
        err = png.Encode(output, input)
        if err != nil {
            panic(err)
        }
    }
    

    错误是:

    panic: runtime error: invalid memory address or nil pointer dereference
    [signal SIGSEGV: segmentation violation code=0x1 addr=0x18 pc=0x4b46e1]
    
    goroutine 1 [running]:
    main.main()
        /home/victor/programs/goprograms/src/v/imagerandvornoi/main.go:71 +0x7a1
    

    第71行是说 r, g, b, a := val.RGBA() . 该VAL插入第63行,或 siteColors[smin] = append(siteColors[smin], input.At(x+minx, y+miny)) 也就是说 input.At 正在返回 nil . 为什么?我怎么修这个?

    1 回复  |  直到 7 年前
        1
  •  1
  •   Tim H.    7 年前

    这与 make() 内置在Go中。 make 特别之处在于它可以采用两个或三个参数:

    make(Type, length) make(Type, length, capacity) . 对于前者, length capacity 设置为相同的值。如果要使用append为切片分配值,则需要使用后一种形式。这是因为两个论点的形式( make(Type, 10) )构建切片 10 当您使用 append() 它成为第11项。

    你打了一个 nil Derefernece在这里是因为你使用的是 制作 使用append,因此切片中的第一个项是 .

    推荐文章