如何在Go编程语言中读取彩色.png文件,并将其输出为8位灰度图像?
发布于 2012-01-02 11:30:11
下面的程序接受一个输入文件名和一个输出文件名。它打开输入文件,对其解码,将其转换为灰度,然后将其编码为输出文件。
此程序不是特定于PNG的,但要支持其他文件格式,您必须导入正确的图像包。例如,要添加JPEG支持,可以将其添加到导入列表_ "image/jpeg"。
如果你只想支持PNG,那么你可以直接使用image/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)
}发布于 2013-06-13 06:22:41
我自己也遇到了这个问题,并提出了一个略有不同的解决方案。我引入了一个实现image.Image的新类型Converted。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)
}发布于 2014-11-17 21:58:03
@EvanShaw的代码片段现在不能工作了,(可能是一些golang API发生了变化)我将其改编如下。遗憾的是,它输出了一个灰度图像,但内容混乱,目前我不知道为什么。我在这里提供给你参考。
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方法。
https://stackoverflow.com/questions/8697095
复制相似问题