如何在Go中打开图像以获取黑白像素的二进制数据?

huangapple go评论82阅读模式
英文:

How to open a image in Go to get binary data of black and white pixels?

问题

我已经尝试了一段时间使用Go以二进制模式打开图像。在Python中,我会使用Pillow和image.open()(rb模式)。示例代码如下:

img = Image.open("PNG.png")
pix = img.getdata()  #其中0代表黑色像素,1代表白色像素

这段代码会以非常干净的二进制形式打开图像,其中只有白色和黑色的点,就像下面的图像一样:

如何在Go中打开图像以获取黑白像素的二进制数据?

在Go中,我尝试使用os.Open(file.jpg)打开文件,我尝试使用image.Decode()解码,我将文件加载到bytes.Buffer中,我尝试使用fmt.Sprintf("%b", data),所有的解决方案都会得到一个字节数组。将该字节数组转换为二进制形式与上面的图像完全不同。我还尝试了encoding/binary,但得到的结果与我想要的不一样。

最近我尝试了以下代码:

package main

import (
	"fmt"
	"image"
	"image/jpeg"
	"io"
	"log"
	"os"
)

// Pixel struct example
type Pixel struct {
	R int
	G int
	B int
	A int
}

func main() {
	// You can register another format here
	image.RegisterFormat("jpg", "jpg", jpeg.Decode, jpeg.DecodeConfig)

	file, err := os.Open("/Users/marcsantiago/Desktop/2033bb1b194adace86f99c7bb7d72e81.jpg")

	if err != nil {
		log.Fatalln("Error: File could not be opened")

	}

	defer file.Close()

	pixels, err := getPixels(file)

	if err != nil {
		log.Fatalln("Error: Image could not be decoded")
	}
	black := Pixel{0, 0, 0, 255}

	for i := range pixels {
		if pixels[i] == black {
			fmt.Print("0")
		} else {
			fmt.Print("1")
		}

	}
}

func getPixels(file io.Reader) ([]Pixel, error) {
	img, _, err := image.Decode(file)

	if err != nil {
		return nil, err
	}

	bounds := img.Bounds()
	width, height := bounds.Max.X, bounds.Max.Y

	var pixels []Pixel
	for y := 0; y < height; y++ {
		for x := 0; x < width; x++ {
			pixels = append(pixels, rgbaToPixel(img.At(x, y).RGBA()))
		}
	}
	return pixels, nil
}

// img.At(x, y).RGBA() returns four uint32 values; we want a Pixel
func rgbaToPixel(r uint32, g uint32, b uint32, a uint32) Pixel {
	return Pixel{int(r / 257), int(g / 257), int(b / 257), int(a / 257)}
}

为了将二进制与我期望的结果进行比较,我将rgba转换为了1和0,其中0表示黑色。但结果仍然不匹配,甚至差距很大。示例图像如下:

如何在Go中打开图像以获取黑白像素的二进制数据?

请帮帮我,我已经没有更多的想法了。PS. 这个网站http://www.dcode.fr/binary-image也可以打开图像并生成我期望的数据。

更新:
这是我正在处理的图像:如何在Go中打开图像以获取黑白像素的二进制数据?

英文:

I've been trying for sometime to open an image in binary mode with Go. In Python I'd use the Pillow and image.open() (rb mode). Example.

img = Image.open(&quot;PNG.png&quot;)
pix = img.getdata()  #where 0 is black and 1 is white pixel

That would open the image with very clean binary of white and black dots like the image below. 如何在Go中打开图像以获取黑白像素的二进制数据? In go I've tried os.Open(file.jpg) to open the file.. I've tried decoding it with image.Decode(), I've loaded the file into bytes.Buffer, I've tried fmt.Sprintf(&quot;%b&quot;, data), all of the solutions give a byte array. Converting that byte array to binary looks nothing like the image above. I've also tried encoding/binary and its the same story with just getting bytes and the binary generated isn't what i want...

Most recently I've tried this

package main
import (
&quot;fmt&quot;
&quot;image&quot;
&quot;image/jpeg&quot;
&quot;io&quot;
&quot;log&quot;
&quot;os&quot;
)
// Pixel struct example
type Pixel struct {
R int
G int
B int
A int
}
func main() {
// You can register another format here
image.RegisterFormat(&quot;jpg&quot;, &quot;jpg&quot;, jpeg.Decode, jpeg.DecodeConfig)
file, err := os.Open(&quot;/Users/marcsantiago/Desktop/2033bb1b194adace86f99c7bb7d72e81.jpg&quot;)
if err != nil {
log.Fatalln(&quot;Error: File could not be opened&quot;)
}
defer file.Close()
pixels, err := getPixels(file)
if err != nil {
log.Fatalln(&quot;Error: Image could not be decoded&quot;)
}
black := Pixel{0, 0, 0, 255}
for i := range pixels {
if pixels[i] == black {
fmt.Print(&quot;0&quot;)
} else {
fmt.Print(&quot;1&quot;)
}
}
}
func getPixels(file io.Reader) ([]Pixel, error) {
img, _, err := image.Decode(file)
if err != nil {
return nil, err
}
bounds := img.Bounds()
width, height := bounds.Max.X, bounds.Max.Y
var pixels []Pixel
for y := 0; y &lt; height; y++ {
for x := 0; x &lt; width; x++ {
pixels = append(pixels, rgbaToPixel(img.At(x, y).RGBA()))
}
}
return pixels, nil
}
// img.At(x, y).RGBA() returns four uint32 values; we want a Pixel
func rgbaToPixel(r uint32, g uint32, b uint32, a uint32) Pixel {
return Pixel{int(r / 257), int(g / 257), int(b / 257), int(a / 257)}
}

So that I can compare the binary against what I expect I converted the rgba to 1 and 0s where 0 == black... it still doesn't match up not even close. Example 如何在Go中打开图像以获取黑白像素的二进制数据?

Help please. I'm out of ideas. PS. This site http://www.dcode.fr/binary-image, also opens the image and generates the data I'm expecting.

UPDATE:
This is the image i'm working with.. 如何在Go中打开图像以获取黑白像素的二进制数据?

答案1

得分: 4

例如,

package main
import (
"bytes"
"fmt"
"image"
"os"
_ "image/jpeg"
)
func main() {
fName := "ggk3Z.jpg"
f, err := os.Open(fName)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// http://www.dcode.fr/binary-image
var txt bytes.Buffer
bounds := img.Bounds()
for y := bounds.Min.Y; y < bounds.Max.Y; y++ {
for x := bounds.Min.X; x < bounds.Max.X; x++ {
r, g, b, _ := img.At(x, y).RGBA()
bin := "0"
if float64((r+g+b))/3 > 0.5 {
bin = "1"
}
txt.WriteString(bin)
}
txt.WriteString("\n")
}
fmt.Fprint(os.Stdout, txt.String())
}
英文:

For example,

package main
import (
&quot;bytes&quot;
&quot;fmt&quot;
&quot;image&quot;
&quot;os&quot;
_ &quot;image/jpeg&quot;
)
func main() {
fName := &quot;ggk3Z.jpg&quot;
f, err := os.Open(fName)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
defer f.Close()
img, _, err := image.Decode(f)
if err != nil {
fmt.Fprintln(os.Stderr, err)
os.Exit(1)
}
// http://www.dcode.fr/binary-image
var txt bytes.Buffer
bounds := img.Bounds()
for y := bounds.Min.Y; y &lt; bounds.Max.Y; y++ {
for x := bounds.Min.X; x &lt; bounds.Max.X; x++ {
r, g, b, _ := img.At(x, y).RGBA()
bin := &quot;0&quot;
if float64((r+g+b))/3 &gt; 0.5 {
bin = &quot;1&quot;
}
txt.WriteString(bin)
}
txt.WriteString(&quot;\n&quot;)
}
fmt.Fprint(os.Stdout, txt.String())
}

huangapple
  • 本文由 发表于 2017年6月12日 05:20:55
  • 转载请务必保留本文链接:https://go.coder-hub.com/44488888.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定