Go で アルファ値ありカラーコードを color.RGBA に変換する方法
Go でアルファ値ありのカラーコードを color.RGBA に変換しようとしたが、alpha-premultiplied color component というのがわからなくて詰まったので結論を記録する。
開発環境
- go version go1.16.5 linux/amd64
本文
今回やりたいのは #A2AD0580 みたいなカラーコードを color.RGBA に変換することである。
リファレンスは下記。
カラーコードを 10 進数に変換する
まずカラーコードは 16 進数なので、10 進数に変換する。
この変換は strconv.ParseInt を使うと行うことができて
hex := "#A2AD0580"
r, err := strconv.ParseInt(hex[1:3], 16, 64)
こんな感じにすると r = 162 が取得できる。同様にして緑、青、アルファ値それぞれ値を取得すればよい。
10 進数のRGBA値から color.RGBA を生成する
10 進数のRGBA値から color.RGBA を生成するのは簡単と思いきや、きちんとリファレンスを見ておかないと失敗する。
color.RGBA の説明にはこのように書いてある。
RGBA represents a traditional 32-bit alpha-premultiplied color, having 8 bits for each of red, green, blue and alpha. An alpha-premultiplied color component C has been scaled by alpha (A), so has valid values 0 <= C <= A.
つまりどういうことかというと、たとえば R: 162, G: 173, B: 5, A: 255 という値は
こんな黄緑色になるので、R: 162, G: 173, B: 5, A: 128 というようにアルファ値を半分にすれば半透明の黄緑色になるのが期待される。
そこでこんなコードを書くと
color.RGBA{
R: uint8(162),
G: uint8(173),
B: uint8(5),
A: uint8(128),
},
こんな色になる。
どう見ても違う色である。
この原因は
An alpha-premultiplied color component C has been scaled by alpha (A)
この記述を無視したことである。
alpha-premultiplied colorとはいわゆる乗算済みアルファ方式というもので、color.RGBA に設定する RGB 値は、アルファ値を 0 ~ 1 として RGB 値に掛け合わせた値を用いなければならない。
つまりこうすると期待した色が得られる。
color.RGBA{
R: uint8(162 * 128 / 255),
G: uint8(173 * 128 / 255),
B: uint8(5 * 128 / 255),
A: uint8(128),
},
透明度を 255 決め打ちでコーディングしていると見逃してしまうし、見逃さなかったとしても乗算済みアルファ方式というのを別途調べないとどうしたらいいかよくわからなかったので、色の取り扱いは難しい。
以上