doutuoben6908 2016-12-27 18:23
浏览 101

在Go中将图像转换为灰度

I'm trying to convert an image to grayscale using Go.

I've found the below code, however, I'm struggling to understand it.

It would be extremely helpful if you could explain what each function is doing and where to define the incoming and outgoing file.

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)
}

I'm quite new to Go so any suggestions or help would be appreciated.

  • 写回答

1条回答 默认 最新

  • douxi4414 2016-12-27 20:10
    关注

    So as Atomic_alarm pointed out, https://maxhalford.github.io/blog/halftoning-1/ explains how to do this succinctly.

    But you're question, if I understand correctly, is about the file opening and creation?

    The first step is to use the image package to Decode the opened file into an image.Image struct:

    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
    }
    

    With this Go image.Image struct, you can convert it to a grayscaled image, image.Gray and then, finally, write or encode the image onto an outgoing file on the disk:

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

    Inbetween the infile opening and outfile creating, you have to, of course, convert the image to grayscale. Again, try the link above, and you'll find this function, which takes an image.Image and returns a pointer to a 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
    }
    

    Concerning the code you provided (and your comment), you were opening a file with os.Args[1], and creating the file os.Args[2]. os.Args is a slice of arguments passed when running the program, 0 will always be the program itself (main), and whatever follows will with 1, 2, etc. The docs states:

    Args hold the command-line arguments, starting with the program name. var Args []string

    so you would run your code above like this:

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

    infile.png must to be a file on disk (inside the directory you are running the code from, or the complete path to file).

    What I have provide above doesn't use os.Args but rather hard codes the file names into the program.

    评论

报告相同问题?

悬赏问题

  • ¥20 win11修改中文用户名路径
  • ¥15 win2012磁盘空间不足,c盘正常,d盘无法写入
  • ¥15 用土力学知识进行土坡稳定性分析与挡土墙设计
  • ¥70 PlayWright在Java上连接CDP关联本地Chrome启动失败,貌似是Windows端口转发问题
  • ¥15 帮我写一个c++工程
  • ¥30 Eclipse官网打不开,官网首页进不去,显示无法访问此页面,求解决方法
  • ¥15 关于smbclient 库的使用
  • ¥15 微信小程序协议怎么写
  • ¥15 c语言怎么用printf(“\b \b”)与getch()实现黑框里写入与删除?
  • ¥20 怎么用dlib库的算法识别小麦病虫害