2016-12-27 214 views
-1

我试图使用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) 
} 

我很新,去所以任何建议或帮助将不胜感激。

+0

看[this](https://maxhalford.github.io/blog/halftoning-1/)文章。 –

回答

2

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

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

的第一步是使用imageDecode打开fileimage.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 
} 

这比赛image.Image结构,你可以将其转换为灰度化图像,image.Gray然后,最后,写或编码图像到盘上的传出文件:

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

Inbe在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等文件规定:

参数数量保持命令行参数,从程序名称开始。 var Args []string

所以你会运行代码,上面是这样的:

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

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

我上面提供的不是使用os.Args而是硬编码将文件名放入程序中。

+0

这是正确的,我在这里挣扎的是,当我用say,“file.png”替换'1'或'2'时,上述代码是如何读入文件的。我得到一个错误,指出'整数片段索引“1.png”' – CS456

+0

你问关于参数吗? “Args保存命令行参数,从程序名称开始。“我更新了我的答案,如果那是你要找的 – Nevermore

+0

好的,谢谢澄清,我现在明白了,我宁愿用文件名硬编码,把我提供的内容转换成什么你有,我只需要改变文件的输入方式? – CS456