透明像素颜色 - Go lang image

我正在尝试根据眼动仪结果创建热图(显示用户最常查看屏幕上的位置)。


对于用户经常查看的像素,我想设置不透明的红色、不太常见的橙色等。我使用红色到绿色的色标。但是对于频率最低的像素,我希望它们不仅显示绿色,还希望它们透明。


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 的图像:(透明)

http://img1.mukewang.com/61d3db67000158b412780715.jpg

alpha RGBA 值设置为 255 的图像:(不透明)

http://img3.mukewang.com/61d3db81000164ba12810718.jpg

据我所知,我正在使用支持透明度的 png 图像。为什么会发生这种情况?有什么想法可以解决这个问题并使最不常见的像素看起来透明?

感谢您的每一个回答。


神不在的星期二
浏览 168回答 1
1回答

慕森卡

这是因为该Set()方法设置(覆盖)指定位置像素的颜色。这不是你想要的。您希望将像素的原始颜色与您选择的颜色相结合,并希望将其作为最终颜色。为此,首先您可以使用 查询原始颜色Image.At(),然后将颜色与您想要的任何颜色组合(您可以分别通过红色、绿色、蓝色和 alpha 通道进行此操作),并使用Set()方法设置最终颜色。结合:请注意,color.RGBA结构的R, G, B,A字段是 alpha 预乘值,这意味着该字段例如保存颜色的红色分量乘以 alpha 通道的值。R您可以使用RGBA.RGBA()将所有字段作为uint32值返回的方法,并且所有字段都在范围内,0..0xffff因此您可以对它们进行操作而不必担心溢出(最大值为uint8is 255,因此即使添加其中的 2 个也很容易溢出)。因此,当您组合 2 种颜色时,您可以按组件组合。但是请注意,这些字段的类型color.RGBA是uint8,因此组合后您必须将结果转换为适合 8 位,因此您必须右移 8。一个非常简单的组合:计算平均值:// Query:x, y := 1, 1r, 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"&nbsp; 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 {&nbsp; &nbsp; r, g, b, a := c1.RGBA()&nbsp; &nbsp; r2, g2, b2, a2 := c2.RGBA()&nbsp; &nbsp; return color.RGBA{&nbsp; &nbsp; &nbsp; &nbsp; uint8((r + r2) >> 9), // div by 2 followed by ">> 8"&nbsp; is ">> 9"&nbsp; &nbsp; &nbsp; &nbsp; uint8((g + g2) >> 9),&nbsp; &nbsp; &nbsp; &nbsp; uint8((b + b2) >> 9),&nbsp; &nbsp; &nbsp; &nbsp; uint8((a + a2) >> 9),&nbsp; &nbsp; }}并使用它:x, y := 1, 1img.Set(x, y, combine(img.At(x, y), color.RGBA{85, 165, 34, 50}))如果您需要逼真的色彩合成,请查看Alpha 合成页面。
打开App,查看更多内容
随时随地看视频慕课网APP

相关分类

Go