【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード

WinXP,Flash8pro,photoshopCS2,IllustratorCSで
オーサリングしています。


フォトショとイラレでPNG画像を作成し、
Flash8Proに読み込んでステージに配置し、
MCに変換してから
hitTestスクリプトで
hitTest(_root._xmouse, _root._ymouse, true)としようとしていますが、
hitTest(_root._xmouse, _root._ymouse, false)で
処理されてしまいます。
FireWorksで作成したFireWorksPNG形式だと
正常にTrueで動作します。

フォトショやイラレのPNGでは透過部分を判別し、True判定できないのでしょうか?

また、どのようにしたらフォトショやイラレのPNGを
Trueで処理できるのでしょうか。
どうぞ宜しくお願い致します。

A 回答 (2件)

#1です。




「色数」は”どのくらい多くの色を識別するか”ではなく、”2つのピクセルの RGB 値にどのくらいの差があったら違う色と見なすか”の設定です。
一般的には、「色数」を小さくするとオリジナルに近い絵に、大きくすると単調な色使いのイラスト風に仕上がります。

私が説明するよりもヘルプに詳しく載っていますので、そちらをご参考になさってください。
最高の精度と思われる設定についても説明があります。
少々重いのですが、LiveDocs ではこちらのページになります。

 ・ Flash ドキュメンテーション:ビットマップからベクターグラフィックへの変換
  http://livedocs.macromedia.com/flash/8_jp/main/0 …

Flash 8 に付属のヘルプでは、「 Flash ユーザーガイド」→「読み込まれたアートワークの使用」→「読み込まれたビットマップの編集」→「ビットマップからベクターグラフィックへの変換」→「+ビットマップからベクターグラフィックに変換するには:」とたどっていくと、同じ記述があります。


ビットマップをトレースしたものは、円などの描画ツールを使用して描いた図形やフリーハンドで描いたイラストよりもアンカーポイントが多くなりがちです。
高精度のトレースであるほどオリジナルに近くなりますが、トレースに時間がかかったり、容量が元の画像とあまり変わらなくなるか、かえって肥大することもあり得ますので、ほどほどにしましょう。

***********************

Illustrator は絵の編集を得意とするソフトですから、Flash よりもきれいにトレースできると思います。
トレースしたイラストは、swf ・ ai ・ eps などで書き出すと Flash に持って行けます。


Flash 8 では、Illustrator 6 ~ 10 までの ai ファイルであれば直接読み込めます。
( Illustrator CS では旧バージョン向けに保存してください。Flash 8 は今のところ、CS 以降の ai ファイルには対応していません)

ただし、Flash では解釈できないデータ(グラデーションメッシュなど)もありますから、Illustrator で描いた絵をそっくりそのまま持って行けるわけではありません。
また、Illustrator と Flash の様々な違いにより、細かい線の欠落や隙間がつぶれる・グラデーションが読み込めない・マスクが外れるなどの症状が出ることもあるようです。

普通の線と塗りだけのイラストであれば ai ファイルでもそれほど深刻な問題は起こらないかと思いますが、最も無難な線は swf ファイルに書き出して持って行くことです。


ちなみに、Illustrator で描いた絵を Flash に持って行く時の注意点は以前別の質問で回答したことがありますので、よろしければご参照ください。

 ・イラレの画像をFLASHで使いたい
  http://okwave.jp/kotaeru.php3?q=1612238

↑ Flash MX の話で対応している ai ファイルのバージョンが古いのですが、swf ファイルで持って行く場合の扱い方は Flash 8 でも同じです。


Illustrator の操作で不明な点がありましたら、「グラフィック」のカテゴリーで質問してみてください。
詳しい方からの回答が付くかと思います。
一応使ってはいますけれど、あまり詳しくありませんので ^^;

-----------------------------------------------------------

ところで、#1の

 > ムービークリップが持っていた BitmapData オブジェクトが使用している自動的に削除されるのかどうかは不明です。

は、意味不明でしたね。
正しくは

 ムービークリップが持っていた BitmapData オブジェクトが使用しているメモリが自動的に解放されるのかどうかは不明です。

です。

考えながらいろいろ書き直しているうちに、文章がおかしくなってしまったようです。
失礼いたしました。
    • good
    • 0
この回答へのお礼

いつもお世話になっております。
最高の設定だと綺麗にできました。
AI(10)で読み込めるとは知らなかったので、
AIがそのままで使えて、こちらの方が断然便利でした。
この度も大変助かり、また詳しく解りやすい解説が
とっても勉強になりました。
どうもありがとう御座いました!

お礼日時:2006/04/19 00:47

Fireworks で保存した PNG ファイルは名前も拡張子も同じく PNG ですが、Fireworks の編集用データを記録するための形式( Flash でいうところの fla ファイルに相当するもの)でもあり、 Photoshop や Illustrator など他のグラフィックソフトが書き出す PNG とは少し違う仕様になっています。



Fireworks の PNG はレイヤーの構成や元のベクトルデータも記録されているので、Flash では、絵を構成するパーツごとに分けて読み込んだり、Flash の描画ツールでも編集できるシェイプとして読み込むことが可能です。
(もちろん、他の PNG と同様に1枚の絵として読み込むこともできます)
パーツ単位に分けて読み込んだ場合はムービークリップシンボルの中に他のシェイプやビットマップシンボルを配置したようなもので、透明部分は空白と同じになります。


Photoshop 等のソフトで作られた PNG ファイルは、透明部分も含めた1枚の絵として読み込まれます。
1枚の絵とは、透明部分は空白ではなく”透明で見えないピクセルがぎっしり詰まっている”ということです。
ピクセルがある以上は hitTest で true(接触している)と判断されるのは当然で、このままでは透明部分を空白として扱うことはできません。

対策は4つほど考えられます。

 1)「ビットマップのトレース」でベクトルデータに変換し、透明部分を削る
 2)ビットマップシンボルを「分解」で分解し、透明部分を「消しゴム」ツール等で削除する
 3)当たり用のムービークリップを内部に配置し、こちらと hitTest をとる
 4) BitmapData クラスの hitTest メソッドを使い、ピクセル単位で判定する


1) ~ 3) は古い Flash でも使える方法です。
写真や色調が細かく変化する絵をトレースすると絵画風のタッチになるところが難点ですが、一般的にはベクトルデータの方が容量が軽くなることから、容量制限が厳しくビットマップ画像を多用できない Flash バナーなどにもよく使われている技法です。
ビットマップの透明部分は削除されますので、トレースした後は普通のムービークリップ同様に絵のある部分だけで hitTest をとることができます。

2) も 1) と似たような方法ですが、手作業になるだけに絵が複雑だと透明部分を削除するのに手間がかかります。
なお、絵の一部を削除しても、swf ファイルには画像の情報が丸ごと書き出されます。
削除した分だけ軽くなるわけではありませんので、絵の周囲の余白部分などの不要な部分はグラフィックソフトで書き出す時に削っておくことをおすすめします。

3) は、バナーでよく用いられる透明なボタンを重ねる技法や、ボタンシンボルの「ヒット」フレームと同じ発想です。
衝突判定をとりたい部分に塗りだけのシェイプを描画し、これをムービークリップにして画像の上のレイヤーに配置します。
普段はアルファを0%にして見えないようにしておき、衝突判定は親の方ではなく、このムービークリップで hitTest をとります。
普通のムービークリップの hitTest と同じで、シェイプのない部分には反応しません。
入れ子になっていますから、親を変形した時はヒット領域も合わせて変化します。

4) は Flash Player 8(作成ツールは Flash 8 )からできるようになった芸当で、元の絵を加工することなくスクリプトだけで対応できます。
ただし、ビットマップの処理は大量のメモリを占有する上に、不要になったらメモリを解放するという、グラフィックソフトではあまり馴染みのない作業が必要になることがありますのでご注意ください。

------------------------------------------------------------

仮に、ステージにアルファチャンネル(透過情報)付きのビットマップを含むムービークリップがあるとします。
ムービークリップの基準点は左上にします。

このムービークリップとマウスカーソルの座標とでピクセル単位で衝突判定をとるスクリプトは、大体、次のようになります。
このスクリプトは、ムービークリップのインスタンスに設定してください。

(↓各行頭に全角のスペースが入っています。コピーする際はご注意ください)


 onClipEvent(load)
 {
  import flash.display.*;
  import flash.geom.*;


  //ビットマップ制御オブジェクトの作成
  //(自分と同じ大きさで、透過あり)
  bmp_obj = new BitmapData( this._width , this._height , true , 0x00ffffff );

  //自分の絵を取り込む
  bmp_obj.draw( this );
 }


 onClipEvent(mouseDown)
 {
  var clip:Point , cursor:Point;


  //絵の左上からの範囲とマウスカーソルを、ピクセル単位で衝突判定
  clip = new Point( 0 , 0 );
  cursor = new Point( this._xmouse , this._ymouse );

  if( bmp_obj.hitTest( clip , 0 , cursor ) )
  {
   /*ここに、接触時の処理を書く*/
  }
 }


今までの Flash はビットマップの処理があまり得意ではなかったのですが、Flash 8 からはスクリプトでも様々なビットマップの処理ができるようになりました。
基本的な扱い方は旧 Macomedia のサイトに講座がありますので、よろしければご参照ください。

 ・ Flash デベロッパーセンター: Flash 8 のイメージ API の概要
  http://www.macromedia.com/jp/devnet/flash/articl …

フィルタをかけるなどのエフェクトも充実していますが、今回はピクセル単位で衝突判定をとる機能を使います。


まず、ムービークリップの絵をビットマップデータとして扱えるように取り込みます。
この処理には BitmapData クラスの draw メソッドを使います。
上記のスクリプトでは、とりあえず絵の左上がムービークリップの基準点にきているものとしているので、かなり手抜きです ^^;
絵の左上が基準点からズレていても補正する汎用的な方法は、あるにはありますが、今回は省略させていただきました。
理論が難しいこともありますけれど、何より余計な仕事が増えて処理が重いので、特に事情がなければ左上を基準点にする方がおすすめです。

**************************

ムービークリップの hitTest は点があるかないかでしか判断できませんが、BitmapData の hitTest では半透明を考慮した衝突判定が可能です。

 if( bmp_obj.hitTest( clip , 0 , cursor ) )

↑この 0 の部分を 255 までの正の整数に書き換えると、255 からその指定の数値までのアルファ値を持つピクセルが不透明と見なされるようになります。
つまり、同じ半透明でもその度合いによって接触しているかいないかを判別することができます。
半透明の判定は、0 に近付けるほど甘く、255 に近付けるほど厳しくなります。
255 を指定すると半透明部分は全て透明と見なされ、完全に不透明なピクセルにだけ反応するようになります。
0 を指定した時は逆に、少しでも透けているピクセルであれば不透明と同じ扱いになり、完全に透明なピクセルだけが false と判断されます。

**************************

今回はとりあえず常に衝突判定をとるだけの作例で、メモリの解放は行っていません。
実際には、衝突判定が不要になった時には

 //メモリを解放
 bmp_obj.dispose();

として、確保したメモリを解放してください。

ムービークリップがステージから消える時に、ムービークリップが持っていた BitmapData オブジェクトが使用している自動的に削除されるのかどうかは不明です。
ムービークリップとオブジェクトだけが消えて確保したメモリは使用中のままだとすると、メモリ内にゴミがたまり、Flash が過度にメモリを占有してシステムに深刻な障害を引き起こす可能性もあります。
スクリプトによるビットマップ操作を行った時は、用が済んだら明示的にメモリを解放してください。

------------------------------------------------------------

普通のムービークリップでも、シェイプとある1点を判定する衝突判定は処理が重くなりがちで、対象が多い場合やリアルタイムで判定をとる場合には不向きです。
BitmapData では確かに精度の高い判定が可能ですが、やはり、メモリの消費と処理の重さが少々気になるところです。
(ちなみに、幅か高さが 2880 ピクセルを超える巨大なビットマップを扱おうとしたり、メモリが不足していて作業領域を確保できなかった場合は BitmapData オブジェクトの作成失敗となり、使用できません)

対象が多い時や処理速度を優先させるなら、四角い形として判定をとるか、画質が落ちたり加工の手間がかかるなどのデメリットはあるけれど MovieClip クラスの hitTest で判定できるようにする方法が、無難ではないかと思います。

この回答への補足

いつもお世話になっております。
さっそく先日のスクリプト達(列挙させる方法や衝突判定)が、まったく別のシステム開発にも役立っております!
解りやすい解説のおかげで、応用させるまでにいたりました。
本当に感謝です^^

今回も詳しい解説を頂きまして本当にありがとうございます。
BitmapDataなども専門書より勉強になりました。
そして、DPE様のおかげで解決させる方法が見つかりました。

 1)「ビットマップのトレース」でベクトルデータに変換し、透明部分を削る
 2)ビットマップシンボルを「分解」で分解し、透明部分を「消しゴム」ツール等で削除する
 3)当たり用のムービークリップを内部に配置し、こちらと hitTest をとる
 4) BitmapData クラスの hitTest メソッドを使い、ピクセル単位で判定する

この1番の「ビットマップのトレース」で
設定を色々変える事でなんとか使えるレベルの
状態にする事ができました。
最高の設定というのがまだわかりませんが、
現在は
色数      500
ノイズの許容量 1
トレースの精度 ピクセル
ポイントの数  多い

で行っています。

これが一番精密に細かく切り抜ける設定なのでしょうか?

どうぞ宜しくお願い致します。

補足日時:2006/04/18 19:48
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!