简体   繁体   English

透明像素颜色 - Go lang图像

[英]Transparent pixel color - Go lang image

I'm trying to create a heat map from eye-tracker results (showing where on the screen was the user looking most frequently). 我正在尝试从眼动仪结果创建一个热图(显示屏幕上用户最常查看的位置)。

For pixels that the user looked frequently onto, I want to set non-transparent red color, for a bit less-frequent orange color, etc.. I'm using red to green color-scale. 对于用户经常看的像素,我想设置不透明的红色,有点不太常见的橙色等。我使用红色到绿色的色阶。 But for the pixels with the least frequency, I want them to not only show green color, I want them to be transparent. 但对于频率最低的像素,我希望它们不仅显示绿色,我希望它们是透明的。

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)

The problem is that when I try to change color for example with img.Set(x, y, color.RGBA{85, 165, 34, 50}) it doesn't actually color the pixel as averaged value depending on old and new color, it just shows some new, strange-looking color. 问题是,当我尝试改变颜色时,例如使用img.Set(x, y, color.RGBA{85, 165, 34, 50})它实际上并没有将像素着色为平均值,具体取决于新旧颜色,它只是显示一些新的,奇怪的颜色。

Image with alpha RGBA value set to 50: (transparent) alpha RGBA值设置为50的图像:(透明)

在此输入图像描述

Image with alpha RGBA value set to 255: (opaque) alpha RGBA值设置为255的图像:(不透明)

在此输入图像描述

I'm using png image that as far as I know does support transparency. 我正在使用png图像,据我所知,它支持透明度。 Why does this happen? 为什么会这样? Any ideas that can solve this problem and make the least-frequently seen pixels appear transparent? 任何可以解决这个问题并让频率最低的像素显得透明的想法?

Thanks for every answer. 谢谢你的每一个答案。

It's because the Set() method sets ( overwrites ) the color of the pixel at the specified location. 这是因为Set()方法设置( 覆盖 )指定位置的像素颜色。 This is not what you want. 这不是你想要的。

You want to combine the original color of the pixel with a color of your choosing, and you want this to be the final color. 您希望将像素的原始颜色与您选择的颜色组合,并希望这是最终颜色。

For this to achieve, first you may query the original color with Image.At() , then combine the color with whatever you want to (you may do this by red, green, blue and alpha channels separately), and set the final color with the Set() method. 为此,首先您可以使用Image.At()查询原始颜色,然后将颜色与您想要的颜色组合(您可以分别通过红色,绿色,蓝色和Alpha通道进行此操作),并设置最终颜色使用Set()方法。

Combining: 结合:

Note that the R , G , B , A fields of the color.RGBA struct are alpha-premultiplied values, which means the R field for example holds the value of the color's red component multiplied by the alpha channel. 请注意, color.RGBA结构的RGBA字段是alpha预乘的值,这意味着R字段例如保持颜色的红色分量乘以alpha通道的值。

You may use the RGBA.RGBA() method which returns all the fields as uint32 values, and all will be in the range of 0..0xffff so you may do operations on them without having to worry about overflow (max value of uint8 is 255 , so even by adding 2 of them could easily overflow). 您可以使用RGBA.RGBA()方法将所有字段作为uint32值返回,并且所有字段都在0..0xffff的范围内,因此您可以对它们执行操作而不必担心溢出( uint8最大值是255 ,所以即使添加其中2个也很容易溢出)。

So when you combine 2 colors, you may combine by components. 因此,当您组合两种颜色时,您可以按组件组合。 But note that type of these fields in color.RGBA is uint8 , so after combining you have to convert the result to fit into 8 bits, so you have to shift right by 8. 但请注意color.RGBA中这些字段的类型color.RGBAuint8 ,因此在组合之后,您必须将结果转换为适合8位,因此您必须向右移动8。

A very simple combining: calculating average: 一个非常简单的组合:计算平均值:

// 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)

You may incorporate this into a helper function: 您可以将其合并到辅助函数中:

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),
    }
}

And using it: 并使用它:

x, y := 1, 1
img.Set(x, y, combine(img.At(x, y), color.RGBA{85, 165, 34, 50}))

Please check out the Alpha compositing page if you need realistic color compositing. 如果您需要逼真的颜色合成,请查看Alpha合成页面。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM