我正在尝试根据眼动仪结果创建热图(显示用户在屏幕上最常注视的位置)。
对于用户经常注视的像素,我想设置不透明的红色,设置不那么频繁的橙色等。 我正在使用红色到绿色的色标。 但是对于频率最低的像素,我希望它们不仅显示绿色,还希望它们是透明的。
imgfile, err := os.Open("unchanged.jpeg")
defer imgfile.Close()
if err != nil {
fmt.Println(err.Error())
}
decodedImg, err := jpeg.Decode(imgfile)
img := image.NewRGBA(decodedImg.Bounds())
size := img.Bounds().Size()
for x := 0; x < size.X; x++ {
for y := 0; y < size.Y; y++ {
img.Set(x, y, decodedImg.At(x, y))
}
}
// I change some pixels here with img.Set(...)
outFile, _ := os.Create("changed.png")
defer outFile.Close()
png.Encode(outFile, img)
问题是,当我尝试使用 img.Set(x, y, color.RGBA{85, 165, 34, 50})
更改颜色时,它实际上并没有变色像素作为取决于新旧颜色的平均值,它只是显示一些新的、看起来很奇怪的颜色。
alpha RGBA 值设置为 50 的图像:(透明)
alpha RGBA 值设置为 255 的图像:(不透明)
据我所知,我正在使用支持透明度的 png 图像。 为什么会这样?有什么想法可以解决这个问题并使最不常见的像素看起来透明吗?
感谢您的每一个回答。
最佳答案
这是因为 Set()
方法设置(覆盖)指定位置像素的颜色。这不是您想要的。
您想将像素的原始颜色与您选择的颜色相结合,并且希望这是最终颜色。
为此,首先您可以使用 Image.At()
查询原始颜色,然后将颜色与您想要的任何颜色组合(您可以通过红色、绿色、蓝色和alpha channel ),并使用 Set()
方法设置最终颜色。
合并:
请注意,color.RGBA 的R
、G
、B
、A
字段struct 是 alpha 预乘值,这意味着例如 R
字段包含颜色的红色分量乘以 alpha channel 的值。
您可以使用 RGBA.RGBA()
方法将所有字段作为 uint32
值返回,所有字段都在 0..0xffff
范围内,因此您可以对它们进行操作而不必担心溢出( uint8
的最大值为 255
,因此即使添加 2 个也很容易溢出)。
因此,当您组合 2 种颜色时,您可以按成分组合。但是请注意,color.RGBA
中这些字段的类型是uint8
,所以合并后你必须将结果转换为8位,所以你必须右移8.
一个非常简单的组合:计算平均值:
// Query:
x, y := 1, 1
r, g, b, a := img.At(x, y).RGBA()
// Combine:
col := color.RGBA{85, 165, 34, 50}
r2, g2, b2, a2 := col.RGBA()
col.R = uint8((r + r2) >> 9) // div by 2 followed by ">> 8" is ">> 9"
col.G = uint8((g + g2) >> 9)
col.B = uint8((b + b2) >> 9)
col.A = uint8((a + a2) >> 9)
// Set new pixel:
img.Set(x, y, col)
您可以将其合并到辅助函数中:
func combine(c1, c2 color.Color) color.Color {
r, g, b, a := c1.RGBA()
r2, g2, b2, a2 := c2.RGBA()
return color.RGBA{
uint8((r + r2) >> 9), // div by 2 followed by ">> 8" is ">> 9"
uint8((g + g2) >> 9),
uint8((b + b2) >> 9),
uint8((a + a2) >> 9),
}
}
并使用它:
x, y := 1, 1
img.Set(x, y, combine(img.At(x, y), color.RGBA{85, 165, 34, 50}))
请查看Alpha compositing如果您需要逼真的色彩合成,请查看页面。
关于image - 透明像素颜色-Go lang图像,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36595687/