Google Chrome または Safari を使用される事を強くお薦めしますw
他のブラウザでは Javascript の処理が重いです(汗)


2010/12/11

画像の合成 その3

では解説です。例によって大したことはしてませんがw

要するに絵の縁の部分を半透明にしてやろうという考えです。
透過色となる背景色が白、絵の縁が黒のイメージを作ったときにその境目がグレーのグラデーションになったとします。こんな具合。

背景がブルー1色だとします。

通常だと透過色である白の部分だけが透過するので合成結果はこうなります。

そこで白の部分の透過率は 100%、黒の部分の透過率は 0% 、グラデーションの部分は徐々に透過率が小さくなるようにします。
実際には透過率ではなく 0 ~ 255 のアルファ値で計算します(透明が 0 で不透明が 255)。
この値を記述するとこんな感じ。
0 0 50 160 200 255 255

このように透過率を変化させることで合成結果をこんな風にしようというわけです。

残念ながら HTML のタグや属性をいくらいじってもピクセル単位で透過率を変えることはできません。
なので canvas を使用します。

canvas に描画した図は全てイメージとして扱われます。つまり DOM のツリーには現れません。
Windows で言うと GDI を使って DC に描画しているようなものです。
canvas に描画された図はピクセル列のデータとして読み取ることができます。またピクセル列のデータを canvas に書きこむことでイメージを表示させることもできます。
Windows の DIBSection みたいなものだと思えば良いかも。Windows API 知ってる人限定の話ですがw

読み取ったピクセルデータは左上から順に R, G, B, A, R, G, B, A, ・・・ と並んでいます。RGBQUAD ですね。データ4つで1ピクセルです。
今回はこの canvas のピクセルデータ列読み書き機能を用いてデータ列中のアルファ値、すなわち RGBA の A の値を書き換えてから、コンテキストに書き戻すことで部分的な半透明の画像を作成・表示しています。

縁の部分だけ半透明にするためには、ピクセルが透過色なのかそれ以外の色なのかを知る必要があります。
これはイメージ全体をなめて調べるしかありません。
ええ、時間かかりますともw

スキャンしていって透過色とそうでない色の境目にぶつかったら、その部分のアルファ値を設定します。
ロジックはそれだけです。

ちょっと面倒なのですが、ピクセルデータを取得するためにはまず一度イメージを canvas に描画しなければなりません。このためピクセルデータを読み取るために一旦イメージを表示する canvas と半透明処理した結果を表示する canvas の2つを用意しています。データ読み取り用の canvas は非表示になってます。

canvas 使用なのでサンプルはブログ埋め込みではなく外部リンクです→こちら

画像をスキャンする間しばらく待たされますが、我慢してください。
このサンプルではソースの可読性も考慮してますので無駄にループが回ってます。実際にはスキャンする部分をもっと効率化する必要があります。そこは自分で工夫してくださいね(^^)v

それから画像の左上(0,0)の位置のピクセルの色を透過色であるとみなしています。よくある手段ではあります。


尚、わざわざ外出しにしておきながらアレですが、実はこのサンプルは IE では動作しません^^;;;;;;;
FlashCanvas 内部でエラーになります。
どこか使い方を間違えているのか、IE 用に何かしないといけないのか、まだ調べていません。
(2010/12/16追記:これまでに以下の事柄が判明しました。
 ・非表示 (style.display='none') の canvas に対しての getImageData 呼び出しがエラーになる
 ・表示状態での getImageData はエラーにはならないが ピクセルデータが取得されない(中身が全て 0)
)

0 件のコメント:

コメントを投稿