保存使用 glReadPixels 读取的图像,其中 alpha 值不是一个

Saving images read with glReadPixels where alpha value is not one

使用 glReadPixels 保存图像时,颜色在其 alpha 值小于 1 的地方扭曲。

表面由 QtQuick 管理。使用 glGetInteger 我发现每个通道有 8 位,包括 alpha。

我可以获得更好的结果,但并不完美,使用类似这样的方法:

for x := 0; x < m.Bounds().Dx(); x++ {
    for y := 0; y < m.Bounds().Dy(); y++ {
        c := m.RGBAAt(x, y)
        w := float64(c.A) / 255
        c.R = uint8(float64(c.R)*w + 255*(1-w) + 0.5)
        c.G = uint8(float64(c.G)*w + 255*(1-w) + 0.5)
        c.B = uint8(float64(c.B)*w + 255*(1-w) + 0.5)
        c.A = 255
    m.SetRGBA(x, y, c)
    }
}

我尝试使用以下方法清除 OpenGL 本身的 alpha 组件:

s.gl.ClearColor(0, 0, 0, 1)
s.gl.ColorMask(false, false, false, true)
s.gl.Clear(GL.COLOR_BUFFER_BIT)

现在的结果和我手动合成的差不多,而且显示和拍摄的图像是一样的,但还是和之前显示的不一样(而且更暗)。

我对 OpenGL/Qt 在显示颜色缓冲区时如何使用 alpha 通道很感兴趣。也许 QtQuick 将它与一个支持层组合在一起?

我通过在绘图期间从不更改 alpha 解决了这个问题。因此,我现在使用 gl.BlendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA) 而不是 gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA),并修改了其他参数以使其看起来像以前一样。

正如 Andon M. Coleman 在他的评论中指出的,这与使用预乘 alpha 混合相同。这样,颜色缓冲区的 alpha 值始终保持为 1,问题就解决了。

glBlendFuncSeparate,分别指定 RGB 和 alpha 分量的像素算法,对于获得相同的结果很有用。