为了账号安全,请及时绑定邮箱和手机立即绑定

如何使用Go编程语言读取彩色的png文件并输出为灰度?

如何使用Go编程语言读取彩色的png文件并输出为灰度?

Go
吃鸡游戏 2021-04-30 14:11:55
如何使用Go编程语言读取彩色.png文件,并将其输出为8位灰度图像?
查看完整描述

3 回答

?
侃侃无极

TA贡献2051条经验 获得超10个赞

下面的程序采用一个输入文件名和一个输出文件名。它将打开输入文件,对其进行解码,将其转换为灰度,然后将其编码为输出文件。


该程序并非特定于PNG,但是要支持其他文件格式,您必须导入正确的图像包。例如,要添加JPEG支持,可以将其添加到导入列表_ "image/jpeg"。


如果你只是想支持PNG,那么你可以使用图像/ png.Decode,而不是直接image.Decode。


package main


import (

    "image"

    "image/png" // register the PNG format with the image package

    "os"

)


func main() {

    infile, err := os.Open(os.Args[1])

    if err != nil {

        // replace this with real error handling

        panic(err.String())

    }

    defer infile.Close()


    // Decode will figure out what type of image is in the file on its own.

    // We just have to be sure all the image packages we want are imported.

    src, _, err := image.Decode(infile)

    if err != nil {

        // replace this with real error handling

        panic(err.String())

    }


    // Create a new grayscale image

    bounds := src.Bounds()

    w, h := bounds.Max.X, bounds.Max.Y

    gray := image.NewGray(w, h)

    for x := 0; x < w; x++ {

        for y := 0; y < h; y++ {

            oldColor := src.At(x, y)

            grayColor := image.GrayColorModel.Convert(oldColor)

            gray.Set(x, y, grayColor)

        }

    }


    // Encode the grayscale image to the output file

    outfile, err := os.Create(os.Args[2])

    if err != nil {

        // replace this with real error handling

        panic(err.String())

    }

    defer outfile.Close()

    png.Encode(outfile, gray)

}


查看完整回答
反对 回复 2021-05-10
?
慕婉清6462132

TA贡献1804条经验 获得超2个赞

我自己遇到了这个问题,并提出了一个略有不同的解决方案。我介绍了一种新类型Converted,它实现了image.Image。Converted由原始图片和组成color.Model。


Converted 每次访问都会进行转换,这可能会导致性能稍差,但另一方面,它却很酷而且很容易组合。


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)

}


查看完整回答
反对 回复 2021-05-10
?
拉丁的传说

TA贡献1789条经验 获得超8个赞

我如下进行调整。可悲的是,它确实输出了灰度图像,但是内容杂乱无章,目前我不知道为什么。我在这里提供它供您参考。


    package main


    import (

        "image"

        "image/color"

        "image/png"

        "math"

        "os"

    )


    func main() {

        filename := "dir/to/myfile/somefile.png"

        infile, err := os.Open(filename)

        if err != nil {

            // replace this with real error handling

            panic(err.Error())

        }

        defer infile.Close()


        // Decode will figure out what type of image is in the file on its own.

        // We just have to be sure all the image packages we want are imported.

        src, _, err := image.Decode(infile)

        if err != nil {

            // replace this with real error handling

            panic(err.Error())

        }


        // Create a new grayscale image

        bounds := src.Bounds()

        w, h := bounds.Max.X, bounds.Max.Y

        gray := image.NewGray(image.Rectangle{image.Point{0, 0}, image.Point{w, h}})

        for x := 0; x < w; x++ {

            for y := 0; y < h; y++ {

                oldColor := src.At(x, y)

                r, g, b, _ := oldColor.RGBA()

                avg := 0.2125*float64(r) + 0.7154*float64(g) + 0.0721*float64(b)

                grayColor := color.Gray{uint8(math.Ceil(avg))}

                gray.Set(x, y, grayColor)

            }

        }


        // Encode the grayscale image to the output file

        outfilename := "result.png"

        outfile, err := os.Create(outfilename)

        if err != nil {

            // replace this with real error handling

            panic(err.Error())

        }

        defer outfile.Close()

        png.Encode(outfile, gray)

    }

顺便说一句,golang无法自动解码图像文件,我们需要直接使用图像类型的Decode方法。


查看完整回答
反对 回复 2021-05-10
  • 3 回答
  • 0 关注
  • 316 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信