为了账号安全,请及时绑定邮箱和手机立即绑定

透明像素颜色 - Go lang image

透明像素颜色 - Go lang image

Go
神不在的星期二 2022-01-04 13:29:53
我正在尝试根据眼动仪结果创建热图(显示用户最常查看屏幕上的位置)。对于用户经常查看的像素,我想设置不透明的红色、不太常见的橙色等。我使用红色到绿色的色标。但是对于频率最低的像素,我希望它们不仅显示绿色,还希望它们透明。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 图像。为什么会发生这种情况?有什么想法可以解决这个问题并使最不常见的像素看起来透明?感谢您的每一个回答。
查看完整描述

1 回答

?
慕森卡

TA贡献1806条经验 获得超8个赞

这是因为该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, 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 合成页面。


查看完整回答
反对 回复 2022-01-04
  • 1 回答
  • 0 关注
  • 167 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号