Golang PNG颜色处理无法达到255。

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

Golang PNG color manipulation won't reach 255

问题

我正在使用的图像是image.png:

Golang PNG颜色处理无法达到255。

当我用254运行我的程序时,它可以正常工作,输出结果如下:

Golang PNG颜色处理无法达到255。

这是我的代码。如果我将254更改为255,输出文件将变为空文件(大小为0字节):

package main

import "fmt"
import "os"
import "bufio"
import "image/png"
import "image"

func main() {
    f, _ := os.Open("image.png")
    im, _ := png.Decode(bufio.NewReader(f))
    img := im.(*image.RGBA)
    s := img.Bounds().Size()
    w := s.X
    h := s.Y
    fmt.Println(w, h)
    newPix := make([]uint8, len(img.Pix))
    iy := 0
    for ; iy < h; iy++ {
        ix := 0
        for ; ix < w; ix++ {
            i := img.PixOffset(ix, iy)
            r := img.Pix[i+0]
            g := img.Pix[i+1]
            b := img.Pix[i+2]
            a := img.Pix[i+3]
            var max uint8 = 254 /*255*/
            newPix[i+0] = uint8(max - r)
            newPix[i+1] = uint8(max - g)
            newPix[i+2] = uint8(max - b)
            newPix[i+3] = uint8(max - a)
        }
    }
    newImg := image.NewRGBA(img.Bounds())
    newImg.Pix = newPix
    o, _ := os.Create("out.png")
    defer o.Close()
    png.Encode(bufio.NewWriter(o), newImg)
    fmt.Println("DONE")
}

为什么会这样,我该如何修复?255仍然是uint8类型,所以应该可以工作...

英文:

The image I'm using as image.png is:

Golang PNG颜色处理无法达到255。

When running my program with 254, it works and the output is:

Golang PNG颜色处理无法达到255。

Here is my code. If I change the 254 to 255, the output file becomes completely empty (0 bytes in size):

package main
import &quot;fmt&quot;
import &quot;os&quot;
import &quot;bufio&quot;
import &quot;image/png&quot;
import &quot;image&quot;
func main() {
f, _ := os.Open(&quot;image.png&quot;)
im, _ := png.Decode(bufio.NewReader(f))
img := im.(*image.RGBA)
s := img.Bounds().Size()
w := s.X
h := s.Y
fmt.Println(w, h)
newPix := make([]uint8, len(img.Pix))
iy := 0
for ; iy &lt; h; iy++ {
ix := 0
for ; ix &lt; w; ix++ {
i := img.PixOffset(ix, iy)
r := img.Pix[i+0]
g := img.Pix[i+1]
b := img.Pix[i+2]
a := img.Pix[i+3]
var max uint8 = 254 /*255*/
newPix[i+0] = uint8(max - r)
newPix[i+1] = uint8(max - g)
newPix[i+2] = uint8(max - b)
newPix[i+3] = uint8(max - a)
}
}
newImg := image.NewRGBA(img.Bounds())
newImg.Pix = newPix
o, _ := os.Create(&quot;out.png&quot;)
defer o.Close()
png.Encode(bufio.NewWriter(o), newImg)
fmt.Println(&quot;DONE&quot;)
}

Why is this and how can I fix it? 255 is still uint8 so it should work...

答案1

得分: 4

我在golang-nuts组的讨论中找到了这个问题之前的讨论。

基本上,输出太小,无法自动触发写入器刷新。手动刷新写入器(在任何情况下都建议这样做)可以解决这个问题。

package main

import "fmt"
import "os"
import "bufio"
import "image/png"
import "image"

func main() {
    f, _ := os.Open("image.png")
    im, _ := png.Decode(bufio.NewReader(f))
    img := im.(*image.RGBA)
    s := img.Bounds().Size()
    w := s.X
    h := s.Y
    fmt.Println(w, h)
    newPix := make([]uint8, len(img.Pix))
    iy := 0
    for ; iy < h; iy++ {
        ix := 0
        for ; ix < w; ix++ {
            i := img.PixOffset(ix, iy)
            r := img.Pix[i+0]
            g := img.Pix[i+1]
            b := img.Pix[i+2]
            a := img.Pix[i+3]
            var max uint8 = 255
            newPix[i+0] = uint8(max - r)
            newPix[i+1] = uint8(max - g)
            newPix[i+2] = uint8(max - b)
            newPix[i+3] = uint8(max - a)
        }
    }
    newImg := image.NewRGBA(img.Bounds())
    newImg.Pix = newPix
    o, _ := os.Create("out.png")
    defer o.Close()
    writer := bufio.NewWriter(o)
    png.Encode(writer, newImg)
    writer.Flush()
    fmt.Println("DONE")
}

忽略错误的常规注意事项适用
英文:

I found a discussion on the golang-nuts group where this issue had come up before.

Basically, the output is too small to automatically trigger the writer to flush. Manually flushing the writer (recommended in any case) fixes the issue.

package main
import &quot;fmt&quot;
import &quot;os&quot;
import &quot;bufio&quot;
import &quot;image/png&quot;
import &quot;image&quot;
func main() {
f, _ := os.Open(&quot;image.png&quot;)
im, _ := png.Decode(bufio.NewReader(f))
img := im.(*image.RGBA)
s := img.Bounds().Size()
w := s.X
h := s.Y
fmt.Println(w, h)
newPix := make([]uint8, len(img.Pix))
iy := 0
for ; iy &lt; h; iy++ {
ix := 0
for ; ix &lt; w; ix++ {
i := img.PixOffset(ix, iy)
r := img.Pix[i+0]
g := img.Pix[i+1]
b := img.Pix[i+2]
a := img.Pix[i+3]
var max uint8 = 255
newPix[i+0] = uint8(max - r)
newPix[i+1] = uint8(max - g)
newPix[i+2] = uint8(max - b)
newPix[i+3] = uint8(max - a)
}
}
newImg := image.NewRGBA(img.Bounds())
newImg.Pix = newPix
o, _ := os.Create(&quot;out.png&quot;)
defer o.Close()
writer := bufio.NewWriter(o)
png.Encode(writer, newImg)
writer.Flush()
fmt.Println(&quot;DONE&quot;)
}

Normal caveats regarding ignoring errors apply.

答案2

得分: 2

我认为你目前的方法尝试改变 alpha 通道是错误的。如果成功,你会将每个透明部分设置为可见,每个可见部分设置为透明,这会使图像看起来毫无意义。

所以,请尝试将你的 newPix[i+3] 行替换为:

newPix[i+3] = a
英文:

I think it is a mistake to try to change the alpha channel the way you are doing. You will set every transparent part to be visible and every visible part to be transparent if you succeed, and that would make the image look like nonsense.

So try replacing your newPix[i+3] line with:

newPix[i+3] = a

huangapple
  • 本文由 发表于 2014年3月1日 10:27:12
  • 转载请务必保留本文链接:https://go.coder-hub.com/22109346.html
匿名

发表评论

匿名网友

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

确定