【问题标题】:Convert an image to grayscale in Go在 Go 中将图像转换为灰度
【发布时间】:2016-12-27 18:23:18
【问题描述】:

我正在尝试使用 Go 将图像转换为灰度。

我找到了下面的代码,但是我很难理解它。

如果您能解释每个函数在做什么以及在哪里定义传入和传出文件,那将非常有帮助。

package main

import (
    "image"
    _ "image/jpeg" // Register JPEG format
    "image/png"    // Register PNG  format
    "image/color"
    "log"
    "os"
)

// Converted implements image.Image, so you can
// pretend that it is the converted image.
type Converted struct {
    Img image.Image
    Mod color.Model
}

// We return the new color model...
func (c *Converted) ColorModel() color.Model{
    return c.Mod
}

// ... but the original bounds
func (c *Converted) Bounds() image.Rectangle{
    return c.Img.Bounds()
}

// At forwards the call to the original image and
// then asks the color model to convert it.
func (c *Converted) At(x, y int) color.Color{
    return c.Mod.Convert(c.Img.At(x,y))
}

func main() {
    if len(os.Args) != 3 { log.Fatalln("Needs two arguments")}
    infile, err := os.Open(os.Args[1])
    if err != nil {
        log.Fatalln(err)
    }
    defer infile.Close()

    img, _, err := image.Decode(infile)
    if err != nil {
        log.Fatalln(err)
    }

    // Since Converted implements image, this is now a grayscale image
    gr := &Converted{img, color.GrayModel}
    // Or do something like this to convert it into a black and
    // white image.
    // bw := []color.Color{color.Black,color.White}
    // gr := &Converted{img, color.Palette(bw)}


    outfile, err := os.Create(os.Args[2])
    if err != nil {
        log.Fatalln(err)
    }
    defer outfile.Close()

    png.Encode(outfile,gr)
}

我对 Go 很陌生,因此我们将不胜感激任何建议或帮助。

【问题讨论】:

标签: go


【解决方案1】:

正如 Atomic_alarm 所指出的,https://maxhalford.github.io/blog/halftoning-1/ 简洁地解释了如何做到这一点。

但如果我理解正确,您的问题是关于文件的打开和创建?

第一步是使用image包将Decode打开的file变成一个image.Image结构体:

infile, err := os.Open("fullcolor.png")
if err != nil {
    return nil, err
}
defer infile.Close()

img, _, err := image.Decode(infile) // img -> image.Image
if err != nil {
    return nil, err
}

使用这个 Go image.Image 结构,您可以将其转换为灰度图像image.Gray,然后最后将图像写入或编码到磁盘上的传出文件中:

outfile, _ := os.Create("grayscaled.png")
defer outfile.Close()
png.Encode(outfile, grayscaledImage) // grayscaledImage -> image.Gray

在infile打开和outfile创建之间,当然,你必须将图像转换为灰度。再次尝试上面的链接,你会发现这个函数,它接受一个image.Image 并返回一个指向image.Gray 的指针:

func rgbaToGray(img image.Image) *image.Gray {
    var (
        bounds = img.Bounds()
        gray   = image.NewGray(bounds)
    )
    for x := 0; x < bounds.Max.X; x++ {
        for y := 0; y < bounds.Max.Y; y++ {
            var rgba = img.At(x, y)
            gray.Set(x, y, rgba)
        }
    }
    return gray
}

关于您提供的代码(和您的评论),您使用os.Args[1] 打开了一个文件,并创建了os.Args[2] 文件。 os.Args 是运行程序时传递的一部分参数,0 将始终是程序本身 (main),随后的任何内容都将与 12 等一起使用。文档指出:

Args 保存命令行参数,以程序名称开头。 var Args []string

所以你可以像这样运行上面的代码:

$ go run main.go infile.png outfile.png

infile.png 必须是磁盘上的文件(在运行代码的目录或文件的完整路径中)。

我上面提供的没有使用os.Args,而是硬编码程序中的文件名。

【讨论】:

  • 没错,我在这里苦苦挣扎的是,当我将“1”或“2”替换为“file.png”时,我提供的上述代码如何读取文件,我得到一个错误指出:'非整数切片索引“1.png”'
  • 你问的是 Args 吗? “ Args 保存命令行参数,以程序名称开头。”我更新了我的答案,如果那是你要找的
  • 好的,感谢您的澄清,我现在明白了。我宁愿像您一样在文件名中硬编码,将我提供的内容转换为您拥有的内容,我只需要更改文件的输入方式?
  • 是的,而不是 os.Open(os.Args[1]) -- 试试 os.Open("infile.png")。确保文件位于运行代码的同一目录中。
猜你喜欢
  • 2010-11-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-01-24
相关资源
最近更新 更多