Alpha 通道(PNG) 和 Golang 的问题

我在 golang 中的图像遇到一个简单的问题。我正在用颜色绘制 png 图像,但结果不是我想要的。


在 Alpha 值最低的像素中,绘制另一种颜色。我正在使用 alphaChannel = false


/* return new image with new color

 * alphaChannel = true get AlphaChannel from given color

 * alphaChannel = false get AlphaChannel from image (x,y) point

 */

func PaintPngImage(img image.Image, cl color.Color, alphaChannel bool) image.Image {

    R, G, B, A := cl.RGBA()

    composeImage := image.NewRGBA(img.Bounds())


    // paint image over a new image

    draw.Draw(composeImage, composeImage.Bounds(), img, image.Point{}, draw.Over)


    // paint new color over the image

    bounds := composeImage.Bounds()

    w, h := bounds.Max.X, bounds.Max.Y


    for x := 0; x < w; x++ {

        for y := 0; y < h; y++ {

            _, _, _, aa := composeImage.At(x, y).RGBA()

            if !alphaChannel {

                A = aa

            }

            realColor := color.RGBA{R: uint8(R),G: uint8(G),B: uint8(B),A: uint8(A)}

            if aa != 0 {

                composeImage.Set(x, y, realColor)

            }

        }

    }


    return composeImage

}


colorLayer := PaintPngImage(layerImage, cl, false)

out, err := os.Create("./output/test.png")

utils.ShowFatalError(err)

err = png.Encode(out, colorLayer)

utils.CloseFile(out) // close file os.Close

utils.ShowFatalError(err) // Show panic log if err != nil

决赛:[ 1 ]


如果我使用 jpeg.Decode 而不是 png.Decode 图像没有奇怪的颜色。


喵喔喔
浏览 93回答 2
2回答

至尊宝的传说

Color.RGBA()返回 范围内的颜色分量0..0xffff,而不是 范围内的颜色分量0..0xff:// RGBA returns the alpha-premultiplied red, green, blue and alpha values// for the color. Each value ranges within [0, 0xffff], but is represented// by a uint32 so that multiplying by a blend factor up to 0xffff will not// overflow.因此,在构造要绘制的颜色时,您必须右移所有 16 位分量(8 位),而不仅仅是转换为,uint8因为该转换保留了最低 8 位,与 16 位值相比,这可能是“随机”的,并且您需要高 8 位:realColor := color.RGBA{     R: uint8(R>>8),     G: uint8(G>>8),     B: uint8(B>>8),     A: uint8(A>>8), }

狐的传说

似乎这个问题也与color.RGBA- 如果我将其与 alpha 一起使用,而不是255在生成的 PNG 中得到奇怪的颜色。在我切换到color.NRGBA(按照接受的答案中的建议)之后,我得到了正确的颜色渲染。所以不要使用newColor&nbsp;:=&nbsp;color.RGBA{ &nbsp;&nbsp;&nbsp;&nbsp;R:&nbsp;uint8(R>>8), &nbsp;&nbsp;&nbsp;&nbsp;G:&nbsp;uint8(G>>8), &nbsp;&nbsp;&nbsp;&nbsp;B:&nbsp;uint8(B>>8), &nbsp;&nbsp;&nbsp;&nbsp;A:&nbsp;uint8(A>>8), }反而newColor&nbsp;:=&nbsp;color.NRGBA{ &nbsp;&nbsp;&nbsp;&nbsp;R:&nbsp;uint8(R>>8), &nbsp;&nbsp;&nbsp;&nbsp;G:&nbsp;uint8(G>>8), &nbsp;&nbsp;&nbsp;&nbsp;B:&nbsp;uint8(B>>8), &nbsp;&nbsp;&nbsp;&nbsp;A:&nbsp;uint8(A>>8), }
打开App,查看更多内容
随时随地看视频慕课网APP