douzhu7507 2016-04-13 10:31
浏览 83
已采纳

透明像素颜色-朗格图像

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.

Image with alpha RGBA value set to 50: (transparent)

enter image description here

Image with alpha RGBA value set to 255: (opaque)

enter image description here

I'm using png image that as far as I know does support transparency. Why does this happen? Any ideas that can solve this problem and make the least-frequently seen pixels appear transparent?

Thanks for every answer.

  • 写回答

1条回答 默认 最新

  • droxy80248 2016-04-13 11:32
    关注

    It's because the Set() method sets (overwrites) the color of the pixel at the specified location. 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.

    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.

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

    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.

    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.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 35114 SVAC视频验签的问题
  • ¥15 impedancepy
  • ¥15 在虚拟机环境下完成以下,要求截图!
  • ¥15 求往届大挑得奖作品(ppt…)
  • ¥15 如何在vue.config.js中读取到public文件夹下window.APP_CONFIG.API_BASE_URL的值
  • ¥50 浦育平台scratch图形化编程
  • ¥20 求这个的原理图 只要原理图
  • ¥15 vue2项目中,如何配置环境,可以在打完包之后修改请求的服务器地址
  • ¥20 微信的店铺小程序如何修改背景图
  • ¥15 UE5.1局部变量对蓝图不可见