簡體   English   中英

Alpha 通道 (PNG) 和 Golang 的問題

[英]Problems with Alpha channel(PNG) and 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圖像已經不奇怪colors了。

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因為該轉換保留了與 16 位值相比可能是“隨機”的最低 8 位,並且您需要較高的 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 中變得奇怪 colors 。 在我切換到color.NRGBA之后(按照接受的答案中的建議),我得到了正確的 colors 渲染。

所以不要使用

newColor := color.RGBA{
    R: uint8(R>>8),
    G: uint8(G>>8),
    B: uint8(B>>8),
    A: uint8(A>>8),
}

反而

newColor := color.NRGBA{
    R: uint8(R>>8),
    G: uint8(G>>8),
    B: uint8(B>>8),
    A: uint8(A>>8),
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM