Visual Basic 6.0 テクニック |
Visual Basic 中学校 > VB6 テクニック >
13.透明
今回のテーマは「透明」です。画像の一部を透明にする方法を説明します。
透明とは「重なっている下のものが透けて見える状態」です。この説明では半透明も透明のうちに含まれるのですが、今回の解説では半透明は扱わないで、完全に透けて見える「透明」だけを解説します。
今回解説すること
●透過GIFを使って画像の一部を透明にする方法
・サンプル画像あり
●マスク処理を使って画像の黒い部分を透明にする方法
・サンプル画像・サンプルコードあり
●未知のテクノロジーを使って画像の任意の一色を透明にする方法
・サンプルダウンロード可
1.簡単な方法
画像の一部を透明にする最も簡単な方法は、「透過GIF」(とうかジフ)を使う方法です。透過GIFとは画像の形式のひとつで、画像そのものに透明情報が埋め込まれているものです。たとえば、下の画像は透過GIF形式です。
画像1:透過GIFの例
この画像の背景が本当に透けているかどうか確認するには、他の画像の上にこの画像を重ねて見なければなりません。
ここで注意してほしいのは「透明」といってもすべてを透過して一番下にあるデスクトップが見えるわけではないという点です。もしフォームや他のウィンドウのすべてを透過して下のデスクトップまで表示したいと思う人には今回の説明は役に立ちません。
「画像が透明であってもウィンドウが透明になるわけではない」という点を気をつけてください。フォームに背景が透明である画像を表示しても透けて見えるのはフォームの地の色です。
VBは透過GIFも普通の画像と同じように扱えるので、プログラムは単純になります。透過GIFを読み込むにはたとえば次のようなコードを書くだけです。
Image1.Picture = LoadPicture("C:\VBSchool\Test.gif")
透過GIFを扱う場合にはこの例のようにImageコントロールを使うことになります。別にPictureBox(ピクチャーボックス)やForm(フォーム)でも透過GIFを読み込むことはできるですがあまり意味はありません。というのは「画像が透明であってもウィンドウが透明になるわけではない」し、PictureBoxやFormはウィンドウの一種だからです。
ところが、Imageコントロールはウィンドウではないので平気で下まで透き通らせることができます。たとえば、次のようにしてみたらいかがでしょう?
Form1.Picture = LoadPicture("C:\Windows\花見.bmp")
Image1.Picture = LoadPicture("C:\VBSchool\Test.gif")
ちゃんとImage1に読み込んだ背景が透けて、下にある 花見.bmp が見えることでしょう。これがImageではなくPictureBoxを使っていたのでは透けて見えるのは花見の画像ではなくPictureBoxの地の色(BackColorプロパティで指定した色)に過ぎません。
さて、では透過GIFを造るにはどうしたらいいでしょうか?これはおそらくとても頑張ればVBのプログラムからでもできるのでしょうがそんな人の話は聞いたことがありません。通常は専用のソフトを使うことになります。専用のソフトといっても多くの人がもっているソフトで十分です。その名は「Photo Editor」(フォトエディター)です。
Photo Editor(フォトエディター)など聞いたことがないと思う人も多いかもしれませんが、実はソフトはMicrosoft社(マイクロソフト)の Office(オフィス)シリーズに添付されているので、Officeを持っている人は多分、知らないうちに持っています。
ただ、Officeにも種類があるのでどのOfficeでも添付されているかと聞かれるとちょっとそこまではわかりません。しかし大部分のOfficeまたは全てのOfficeには添付されているものと思っています。
Photo Editorがあなたのパソコンにインストールされている場合スタートメニューのプログラムの一覧の中に[Microsoft Office ツール]という項目があり、その中に[Microsoft Photo Editor]があります。古いバージョンのOfficeではふたーとメニューの直下に[Microsoft Photo Editor]があります。
しかしながら、このPhoto Editorは標準ではインストールされないため、インストールしていない人を多く見かけます。追加インストールするにはOfficeのCDをパソコンにセットして指示に従ってください。インストールする項目を指定するところで必ずこのPhoto Editorを見つけ出してチェックを入れなければなりません。わからない場合は全てインストールすれば当然Photo Editorもインストールされます。
実際に画像を透過GIFにする手順を説明しましょう。元となる画像は自分で用意しなければなりません。インターネットで適当な画像をダウンロードしても言いし、とりあえずPaint(ペイント)で適当な絵を描いて使ってもかまいません。透過GIFでは透明にできるのは1色だけなのでその点は注意してください。また透過GIFは256色以上の色は保存できません。256色以上使っている画像を透過GIFに変換しようとすると、強制的に256色にされてしまします。当然見栄えは悪くなります。
画像の用意ができたらPhoto Editorを起動して画像を読み込んでください。
画像を読み込んだら[ツール]メニューの[透明色に設定]を選択して、画像の中から透明にしたい色をクリックします。調節のダイアログが出てくるのでOKをクリックすると選択した色が透明色となり、灰色のチェック模様で表示されます。そして、この画像をGIF形式で保存すれば透過GIFのできあがりです。
なお、GIF形式で画像を保存する技術に関してはどこかの会社が知的所有権を有しているので、その会社の許諾を得ずにこの機能を自分の作ったソフトに搭載することは違法です。そのため透過GIFを作成できるフリーソフトというものはまずありません。もちろん、表示するだけなら無料ですので、表示機能のあるソフトはたくさんあります。
2.透過GIFの欠点
今までの説明ですで気づかれた点もあるでしょうが、それに加えて透過GIFには欠点がいくつかあります。ここでそれらをまとめておきましょう。
・256色以上ある画像は透過GIFにできない。
・VBから表示するときにbmpに比べて処理が重い。
・連続して透過GIFを表示させよう等すると背景がちらつく。
このような欠点のため、透過GIFはアクションゲームやシューティングゲームなどのように透明画像を短い時間に大量に必要とするアプリケーションには向きません。
ただし、透明な静止画、またはしごくゆっくりした透明画像の移動を扱う場合には手軽さの点から見て透過GIFは優れた機能であなたを満足させてくれるでしょう。
3.マスク処理
次に透過GIFから離れて、普通のbmp形式の画像の一部または全部を透明にする方法を説明しましょう。もっとも一般的なのはマスク画像を使った処理です。
今度は初めにサンプルプログラムをご覧に入れましょう。
Option Explicit Private Const PICTURE_BACK As String = "\T13_Back.Jpg" Private Const PICTURE_CHARA As String = "\T13_Chara.GIF" Private Const PICTURE_MASK As String = "\T13_CharaMask.GIF" Private Sub Command1_Click() picMain.Picture = LoadPicture(App.Path & PICTURE_BACK) picChara.Picture = LoadPicture(App.Path & PICTURE_CHARA) picMask.Picture = LoadPicture(App.Path & PICTURE_MASK) Call picMain.PaintPicture(picMask.Picture, 0, 0, , , , , , , vbSrcAnd) Call picMain.PaintPicture(picChara.Picture, 0, 0, , , , , , , vbSrcInvert) End Sub |
使用している画像はここにも貼り付けておきますので、試して見たい方は右クリックでこれらの画像を保存してやってみてください。
左:画像2:T13_Chara.gif 右:画像3:T13_CharaMask.gif
画像4:T13_Back.jpg 登呂遺跡
このT13_Back.jpgの画像は以下のサイトの好意により使用させていただいているものです。
インターネットの世界では不特定多数に発信することになるので当サイトのようなマイナーな所でも著作権に配慮する必要があります。著作権フリーまたは条件付著作権フリーで画像を提供してくださる方々には感謝します。 |
さて、背景が透明になるのは T13_Chara.gif です。やっていただければわかります。gif画像を編集できるソフトを持っている場合には色を変えたりしてみてください。但し、絵の形(まるっこい顔の形)を変えてはいけません。形を変えると透明にできなくなります。
透明になる部分はT13_Chara.gifで黒くなっていて、かつT13_CharaMask.gifで白くなっている部分なのです。つまり、2つの画像を組み合わせて透明を実現しているのです。
これが「マスク処理」といわれる方法で、T13_CharaMask.gifのように表には表れず、透明になるように手助けしている画像のことをマスク画像と言います。
それでは、背景が透明になる仕組みを説明しましょう。
まず、このプログラムにはPaintPictureメソッドが2つありますが、その下の方をコメントアウトして実行してみてください。
そうするとわかるのですが、マスク画像が背景が透明になって表示されます。これを見ると「なんだ、画像1つでも透明にできるじゃないか」と思われるかもしれませんが、実はこの方法では白い部分だけが透明になり、黒い部分だけが正常に表示されます。そのため、マスク画像には白と黒以外の色は使用しないのです。
もし、マスク画像に赤や青などの色が使われていた場合には赤や青の部分はその背景(この例では登呂遺跡)の色と混ざって合成されてしまいます。合成を逆手にとって面白い画像効果を付けてもいいのですが今回のテーマは画像効果ではなく「透明」なので合成されては困ります。
どのように合成するかはPaintPictureメソッドの最後の引数で指定しています。vbSrcAndが指定されているので背景画像とマスク画像は色のAnd演算を使って合成されます。白は値が 0 なので透明になるのです。黒は値が最大なので他の色とAnd演算を実行しても色が変わらないのです。
ここで2行目のPaintPictureをみてみましょう。最後の引数が、vbSrcInvertになっていますね。これは排他的論理和を使って色を合成することを意味しています。…と書いてもまず理解不能でしょう。結論をいうと vbSrcInvertで色を合成すると背景が黒の場合にはキャラクターの画像の色はまったく変更されないということです。また、キャラクターの画像が黒の部分に関してはこの逆で背景の色はまったく変更されないのです。
したがって初めにvbSrcAndでマスク画像を転送してから、vbSrcInvertでキャラクターの画像を転送すればうまい具合にキャラクターの画像の黒い部分が透明になったかのような結果が得られるというわけです。
透明の正体は透明にするようにコンピュータに特別な指示しているのではなく、2段階に分かれた色の論理演算の結果だったのです。
4.マスク画像の作り方
あなたが複雑な絵を描いたとしてその背景をマスク処理を使って透明にさせるにはどうしたらよいでしょうか?
まず、背景を黒にする必要があります。黒い部分だけが透明にできるからです。そうするとあなたの絵には背景以外には黒は使えないことになりますね。しかし黒のような重要な色を使わないわけにも行きません。そこで絵の黒くしたい部分には黒にそっくりな別の色を使います。人間の目には同じように黒に見えてもコンピュータにはちゃんと区別されるわけですから。
次にその絵のマスク画像を作る必要があります。これは自分で地道に絵を黒い部分と白い部分に塗り分けてもいいのですがどうもマスク画像を作ってくれるソフトがあるらしいですね。私はよく知らないのですが…。
ちなみに私はペイントを使って地道にマスク画像を作るか、前述のPhotoEditorの明るさの調整機能を利用してマスク画像を作っています。しかし、明るさの調整機能といってもそんな大して機能じゃないのでまねすることはおすすめできません。どのみち私はマスク画像などあまり作らないのでこの程度で用が足りるのです。
5.マスク処理の欠点
マスク処理も透過GIFに比べて色数に制限がない点や、使用するメモリが少ない点などで優れていますが以下のように欠点もあります。
1.マスク画像が必要
2.黒しか透明にできない。
3.画像の色に黒が使えない(但し、黒に似た色をつかえばよい)
これらを克服することは原理的に不可能です。もちろん、自動的にマスク画像を作るプログラムなどを作ればあらかじめマスク画像を用意する必要はないのですが、結局マスク画像が必要という点はかわりません。
6.禁断の技
透過GIFも使わず、マスク処理も行わないで背景を透明にする方法があります。しかもこの方法では好きな色を透明にすることができます。そして、どの色を透明にするかはプログラム中で指定できるのであらかじめ透明にするために画像を設定しておく必要もありません。まさに透過GIFとマスク処理もいいところをあわせて様な夢の方法です。
しかし、私はこの方法の原理を理解していません!
そのため説明はできませんが、私の記事を読んでくださっている皆さんのためにサンプルだけは掲載しておきます。
これをどう利用するかはあなたしだいです!
TransBMP.lzh 約20KB
ファイルにはvbpファイルなどソースと画像ファイルが含まれています。exeファイルは含まれていません。
このサンプルは私が手を加えて使いやすくはしてありますが、原理は不明です。もともとのプログラムはマイクロソフト社が提供しているものです。どうもGDI系のAPI関数を駆使して透明を実現しているようですね。やはり論理演算を行っているようで別にマイクロソフト社だけが知っている秘密のAPI関数を使っている形跡はないです。
原理がわかった人はぜひ投稿して教えてください!