組み込みの埋まってるとこ

システム寄りの組み込みCプログラミングBLOG

Premultiplied Alphaというカラーフォーマットについて

OpenVGやWin2D等、グラフィックスライブラリのAPIでたまにプリマルマルチプライドαというカラーフォーマットが使われているのを見かけることがあります。 これはどんなカラーフォーマットで何のために使われるのでしょう。

αブレンド

一般に半透明の色を扱いたいときはRGBのカラーと透明度を表すαをセットにしたカラーフォーマットを使います。

描き込み元の色と透明度をそれぞれsrc.RGB、src.A、描き込み先の色をdst.RGBとすると、 これらを透明度の割合に応じてブレンドして得られる色result.RGBは次の式のようになります。

result.RGB = (src.RGB * src.A) + (dst.RGB * ( 1 - src.A) … 式(1)

乗算の演算コストを下げる

上記の式(1)をよくみるとコンピュータでは演算コストが高いと嫌われる乗算が2つも使われています。 これをなんとか減らせないものかと考えられたカラーフォーマットがプリマルチプライドα(以下、プリマルαと省略)です。

プリマルαでは予めのカラーRGBに透明度αを乗算した状態でデータを用意します。 これによりブレンドするときわざわざその場で乗算する演算コストを省くことができるというわけです。

予め透明度αを乗算したプリマルαの状態であるカラーRGBをsrc.R'G'B'とすると先ほどの式(1)は次のようになり、 乗算が1つになっているのが分かります。

src.R'G'B' = src.RGB * src.A

result.RGB = src.R'G'B' * ( 1 - src.A) … 式(2)

プリマルチプライドαであるデータの作り方

一般的な画像ツールでプリマルαでデータを保存できるものはあまり多くありません。 プリマルαはコンピュータに優しすぎるフォーマットでデザイン等の用途にはあまりにも不向きです。 プリマルαが必要になったときは簡単な自作プログラムで変換することになるでしょう。

しかし何もしなくてもプリマルαとして扱うことができる画像は結構あります。 写真のように透明なピクセルがまったくない画像はそのままでRGBにα=1が乗算済みのプリマルα対応であると見なすことができます。 記号等の画像で背景を抜くために完全透明(α=0)と完全不透明(α=1)の2種類でしか透明を使っていない画像も完全透明のピクセルが黒(R=0,G=0,B=0)であれば同様にプリマルα対応と見なすことができます。 本当にプリマルαに変換する必要があるのは縁取りのアンチエイリアスやカラーステンドガラスのように多段階で透明度が使われている画像だけになります。

まとめ

OpenVGではブレンドにプリマルαを前提としたブレンドモードしかなくて面食らうのですが、 落ち着いて考えるとプリマルα対応済として扱える画像は結構あります。 それも見越してのプリマルαなのかもしれません。

半透明にしたときどうしても色が少しおかしいというときはブレンドモードがプリマルαを前提としていないかも確認してみるとよいでしょう。

関連記事