selflearn @ ウィキ

Alpha Compositing - Part II-2

最終更新:

selflearn

- view
メンバー限定 登録/ログイン

Alpha Compositing - Part II (2)


開始日 2007年03月19日
最終更新日 2009年06月03日

はじめに

Alpha Compositing - Part Iで説明した方法を応用し、Web2.0的な画像を作成する方法について説明・使い方を記しています。
全4ページのうち、ここは2ページ目です。

原著


「Alpha Compositing - Part II - Page2」
http://rmagick.rubyforge.org/web2/web2-2.html

注意

  • もともと個人利用を目的として日本語化したために、けっこう意訳している部分があります。「意味分からないよ」とか「おかしいんじゃない?」とかいうのがあれば、オリジナルを参照するか、コメントで質問してください(がんばって調べます)。

更新履歴

  • 2008/3/19 作成開始
  • 2008/3/24 とりあえず1回目の翻訳完了。あとはチマチマ直していこう。


訳文



アノテーション(Annotation)

画像にテキストを追加することはアノテーションと呼ばれ、Drawクラスのannotateメソッドによって取り扱われる。"RMAGICK"を追加するわけだけど、Drawクラスのインスタンスを作り、いくつか属性をセットした後でannotateメソッドをコールするんだ。
gc = Draw.new
gc.fill = 'white'
gc.stroke = 'none'
gc.pointsize = 42
gc.annotate(background, 0, 0, 70, HEIGHT, "RMAGICK")
annotateメソッドの引数はシンプルだ。最初の2つはテキストの回転角度をx-y軸で指定する。ここではx,yどちらも0だ。次に3-4番目の引数は、テキストのx-y軸でのオフセット量を示す。今回は左に70ピクセル、上下中央になるよう設定しているよ。
これによってこんな画像が出来上がる(予想できたかい?)。

imageプラグインエラー : 画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
(場合によっちゃfont=属性を使ってフォントをデフォルトから変更したいこともあるだろう。でも今回は字面の良さからデフォルトそのままで使用しているからね)

透明度付きの合成(Composition with transparency)

RMAGICKテキストの反射イメージを描くことはそう簡単じゃないんだ。反射しているように見せるには、透明度という概念を考えなければならない。最終的に出来上がる画像をもう一度よく見てみてごらん。反射しているものはたいてい透明だけれども、すぐ近くの影から影の先端に至るまでには透明度が変化しているだろう?このエフェクトを使うには、グレースケールで透明度を示す画像を用意し、それをサカサマになった(=反射している)RMAGICKに透明度として適用するんだ。

画像の透明度に関する情報はαチャネルと呼ばれる。R/G/Bのように、0~255(←RGBのMAXと同じ)の範囲の値を持ち、もしRGBMaxに対して100%だったら完全に透明になる(から見えなくなっちゃうね)。逆に0だったら、不透明でRGB画像そのままになる。copy-opacityによる合成方法は、元画像の透明度の情報を合成先画像にコピーするよ。
このcopy-opacity、元画像の種類により2種類の動作を使い分けている。

  1. もし元画像がαチャネル情報を持っている場合、copy-opacityは単純に元画像のαチャネル情報を合成先画像の対応するピクセルにコピーする
  2. もし元画像がαチャネル情報を持っていない場合、copy-opacityは元画像の輝度を計算してαチャネル情報とし、それを合成先画像の対応するピクセルにコピーする。元画像の輝度は次の数式で計算する:
    I = 0.299*R + 0.587*G + 0.114*B
    copy-opacityは合成先画像のαチャネルを「MaxRGB - I」に設定する。つまり、輝度が高い==より不透明というわけだ。

このうち、反射画像に対する透明度のマスクを作るには2番目の方法が適しているよ。なぜかって?輝度の数式をグレイスケール画像(R=G=B)に当てはめると、ピクセルの黒さがそのまま透明度にあてはまるからだ。真っ黒(#000000)なピクセルは輝度0だから100%の透明度になり、明るくなるほど透明度が下がっていく。やがて真っ白(#ffffff)なピクセルで0%の透明度を示すのは分かるよね。

ストライプ下端のブルーグレイ部分のコピーを作り、文字列RMAGICKを記述する。反射した画像は上下逆に映るからflipメソッドを使ってひっくり返してくれ。
reflection = stripes[1].flip
reflection.composite!(color, CenterGravity, ColorizeCompositeOp)
gc.annotate(reflection, 0, 0, 70, HEIGHT, "RMAGICK")
imageプラグインエラー : 画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
下の2行で黒から濃い灰色へと遷移するグラデーション画像を作っている。一番暗い色(=黒)が上端、明るい色が下端だ。
grad = GradientFill.new(0, 0, WIDTH, 0, "black", "gray35")
opacity_mask = Image.new(WIDTH, HEIGHT, grad)
imageプラグインエラー : 画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
君が知っておかなければならない最後のトリックは、合成先画像のmatte属性がfalseだとαチャネルが無視されてしまうことだ。matteがtrueなら(αチャネルを)考慮してくれる。
だから次の3行はこうなる。

  1. 合成先画像のαチャネルを有効化
  2. copy-opacityに強制的に2番目の動作を行わせるよう、マスク画像のmatteを無効化
  3. copy-opacityによるマスク画像の輝度を、反射画像(元画像)の透明度として合成
reflection.matte = true
opacity_mask.matte = false
reflection.composite!(opacity_mask, CenterGravity, CopyOpacityCompositeOp)
最後に出来上がった画像をflipメソッドでひっくり返して、作成している画像の下端に対して合成してやるんだ。
reflection.flip!
background.composite!(reflection, SouthWestGravity, OverCompositeOp)
imageプラグインエラー : 画像を取得できませんでした。しばらく時間を置いてから再度お試しください。
ちなみに、この反射させるエフェクトはフォントがディセンダを持っているときにはうまくいかないことに注意しておいてほしい(ディセンダとは文字が基線より下に延びる部分を意味するよ。たとえば'g'のフックの部分のようにね)。なぜかって、センターラインを越えてしまう部分が出てきてしまうからだ。Mr. Maloneyは賢いことに小文字に小さな大文字を使うことで問題を回避している。まぁ、賢い私も全て大文字にすることで回避したんだけどね。

さて、次はいよいよ星形の図形を追加するよ。

参考サイト(訳者による追加)



-

タグ:

Ruby RMagick
ウィキ募集バナー