在Go中将图像转换为灰度

时间:2016-12-27 18:23:19

标签: go

我正在尝试使用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的新手,所以任何建议或帮助都会受到赞赏。

1 个答案:

答案 0 :(得分:2)

正如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),随后的任何内容都将1,{{1}等文档说明:

  

Args保存命令行参数,从程序名称开始。   2

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

var Args []string

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

我上面提供的内容并没有使用$ go run main.go infile.png outfile.png 而是将硬代码文件名用于程序。