英文:
Does Go have library which opens paletted png of 2 bit color-depth?
问题
如何使用Go读取基于调色板的PNG图像?
对于Python中的图像,我可以简单地执行以下操作:
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])
在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[%3d] = %5d,%5d,%5d,%5d\n", i, cr, cg, cb, ca)
}
}
img, err := png.Decode(f)
if err != nil {
log.Fatal(err) // 在这里失败!
}
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")
}
在解码时会抛出"png: invalid format: not a PNG file"的错误。
如果我在Mac终端上使用file
命令,它会显示:
image.png: PNG image data, 100 x 100, 2-bit colormap, non-interlaced
而VsCode可以正常显示该图像。
我尝试了从Adobe Illustrator创建的图像和从下面的代码生成的图像。两者都遇到了相同的错误:
func createPNG() {
// 创建具有所需尺寸的新图像
img := image.NewPaletted(image.Rect(0, 0, 100, 100), color.Palette{
color.RGBA{255, 0, 0, 255}, // 红色
color.RGBA{0, 255, 0, 255}, // 绿色
color.RGBA{0, 0, 255, 255}, // 蓝色
})
// 在图像中设置像素颜色
for x := 0; x < 100; x++ {
for y := 0; y < 100; y++ {
switch {
case x < 50 && y < 50:
img.SetColorIndex(x, y, 0) // 将像素(x, y)设置为红色
case x >= 50 && y < 50:
img.SetColorIndex(x, y, 1) // 将像素(x, y)设置为绿色
case x < 50 && y >= 50:
img.SetColorIndex(x, y, 2) // 将像素(x, y)设置为蓝色
default:
img.SetColorIndex(x, y, 3) // 将像素(x, y)设置为透明
}
}
}
// 创建一个新文件来保存PNG图像
file, err := os.Create("image.png")
if err != nil {
panic(err)
}
defer file.Close()
// 将图像编码为PNG并保存到文件中
err = png.Encode(file, img)
if err != nil {
panic(err)
}
}
英文:
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[%3d] = %5d,%5d,%5d,%5d\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)
}
}
答案1
得分: 1
在你的情况下,问题似乎不是图像的格式,而是你使用图像文件的方式。
我假设你首先将其传递给image.DecodeConfig()
(代码中没有显示,但cfg
必须已经初始化),然后传递给image.Decode()
。
问题在于,在第一次调用后,你的文件具有偏移量,但第二次调用假设它从文件的开头开始读取。
你可以通过在读取配置后将文件倒回来解决这个问题:
file.Seek(0, io.SeekStart)
英文:
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)
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论