2016-04-13 178 views
3

我想從眼動儀結果(顯示屏幕上用戶最常看的位置)創建熱圖。透明像素顏色 - 去朗圖像

對於用戶頻繁查看的像素,我想設置不透明的紅色,不太常見的橙色等。 我使用紅色到綠色的色階。 但是對於頻率最低的像素,我希望它們不僅顯示綠色,我希望它們透明。

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})它實際上沒有顏色的像素爲依賴於新舊顏色平均值,它只是顯示了一些新的,奇怪的顏色。

圖像的設置爲50的α值RGBA:(透明)

enter image description here

圖像的設置爲255的α值RGBA:(不透明)

enter image description here

我使用png形象,據我所知支持透明度。 這是爲什麼發生?任何想法可以解決這個問題,並使最少見的像素看起來透明?

感謝您的每一個答案。

回答

2

這是因爲Set()方法設置(覆蓋)在指定位置像素的顏色。這不是你想要的。

您想要將像素的原始顏色與您選擇的顏色相結合,並且希望這是最終的顏色。

爲達到此目的,首先您可以用Image.At()查詢原始顏色,然後將顏色與您想要的任意顏色組合(您可以分別通過紅色,綠色,藍色和Alpha通道完成此操作),並設置最終顏色與Set()方法。

結合:

注意,RGB,所述color.RGBA結構的A字段是α-預乘值,這意味着,例如在R字段保持的顏色的紅色分量乘以值alpha通道。

您可以使用RGBA.RGBA()方法,它返回的所有字段爲uint32值,以及所有將在0..0xffff的範圍內,所以你可以這樣做對他們的操作,而不必擔心溢出(的uint8最大值爲255,所以即使加入其中的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頁面,如果你需要逼真的色彩合成。