英文:
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中,我尝试使用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表示黑色。但结果仍然不匹配,甚至差距很大。示例图像如下:
请帮帮我,我已经没有更多的想法了。PS. 这个网站http://www.dcode.fr/binary-image也可以打开图像并生成我期望的数据。
英文:
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("PNG.png")
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. 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("%b", 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 (
"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)}
}
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
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.
答案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 (
"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())
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论