How do you read a palette-based PNG image with Go?
For an image in Python I can simply do:
from PIL import Image
im = Image.open('image.png')
pix = im.load()
for i in range(100):
for j in range(100):
print(pix[i, j])
Using Go:
f, err := os.Open("image.png")
if err != nil {
log.Fatal(err)
}
defer f.Close()
pal, ok := cfg.ColorModel.(color.Palette) // ok is true
if ok {
for i := range pal {
cr, cg, cb, ca := pal[i].RGBA()
fmt.Printf("pal[=] = ],],],]\n", i, cr, cg, cb, ca)
}
}
img, err := png.Decode(f)
if err != nil {
log.Fatal(err) // Fails here!!
}
for y := img.Bounds().Min.Y; y < img.Bounds().Max.Y; y {
for x := img.Bounds().Min.X; x < img.Bounds().Max.X; x {
log.Println("img.At(x, y):", img.At(x, y))
}
fmt.Print("\n")
}
It'll go to throws "png: invalid format: not a PNG file" when decoding.
If I use the file
command on Mac shell it says:
image.png: PNG image data, 100 x 100, 2-bit colormap, non-interlaced
And VsCode render the image just fine.
I tried it both on an image created from Adobe Illustrator and one generated from the below code. Both run into the same error:
func createPNG() {
// Create a new image with the desired dimensions
img := image.NewPaletted(image.Rect(0, 0, 100, 100), color.Palette{
color.RGBA{255, 0, 0, 255}, // Red
color.RGBA{0, 255, 0, 255}, // Green
color.RGBA{0, 0, 255, 255}, // Blue
})
// Set the pixel colors in the image
for x := 0; x < 100; x {
for y := 0; y < 100; y {
switch {
case x < 50 && y < 50:
img.SetColorIndex(x, y, 0) // Set the pixel at (x, y) to red
case x >= 50 && y < 50:
img.SetColorIndex(x, y, 1) // Set the pixel at (x, y) to green
case x < 50 && y >= 50:
img.SetColorIndex(x, y, 2) // Set the pixel at (x, y) to blue
default:
img.SetColorIndex(x, y, 3) // Set the pixel at (x, y) to transparent
}
}
}
// Create a new file to save the PNG image
file, err := os.Create("image.png")
if err != nil {
panic(err)
}
defer file.Close()
// Encode the image as a PNG and save it to the file
err = png.Encode(file, img)
if err != nil {
panic(err)
}
}
CodePudding user response:
The problem in your case seems to be not the format of the image, but rather the way you use the image file.
I assume you first pass it to image.DecodeConfig()
(the code doesn't show it but cfg
must have been initialized) and later to image.Decode()
.
The problem is that after the first call your file has an offset but the second call assumes that it is reading from the beginning of the file.
You can solve this by rewinding the file after reading the configuration:
file.Seek(0, io.SeekStart)