2016-12-27 280 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