トップへ戻るニュースフォーラムFLASH-ML 過去ログBak@Flaダウンロードよくある質問と答
ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
メインメニュー
メイン
   とにかくFLASH【FLASHに関して全般】
     swfmillでGIF画像の置換について
投稿するにはまず登録を

スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
takemaru
Åê¹ÆNo.44991
投稿日時: 2010-5-24 18:31
新米
居住地:
投稿: 6
使用環境:
swfmillでGIF画像の置換について
GIFはswfの中に独自形式(DefineBitsLossless)に変換されて保持されてます、
なので違うGIFに置き換えるためには同じ変換をそのGIFにかけたあと置き換える必要があります。
しかし、変換仕様に下記サイトなどを参考にして、SWFに埋め込んである画像文字列データをxml化したデータを確認し、同様の変換文字列が作成できるか、
逆に文字列データから画像データに戻してみようとしてみたり、試行錯誤してみたのですが、力及ばず。。。できませんでした。
環境は、PHPは5.2.2、swfmillのバージョンは、0.2.12になります。
※テキスト、JPG画像の置換は問題なくできました。

▼主に参考にさせて頂いたサイトになります。
http://blog.ps-ax.info/2010/05/swfmill%E3%81%A7gif%E3%81%AE%E7%BD%AE%E3%81%8D%E6%8F%9B%E3%81%88/

http://q.hatena.ne.jp/1267196042

http://blog.ville.jp/2010/03/04/168

http://pwiki.awm.jp/~yoya/?Flash/SWF/format/Lossless

何かご存知の方がいましたら、アドバイスなど頂けましたら非常に助かります。
お忙しいところお手数お掛けしますが、よろしくお願いいたします。
961832p
Åê¹ÆNo.45002
投稿日時: 2010-5-25 17:24
常連
居住地: Akiruno-shi
投稿: 155
使用環境:
 
:AS3:
- Adobe Flex SDK, Eclipse, AIR GEAR
- LB.Log AS3, Alcon2

:AS2:
- AMES(ASDT, MTASC, Eclipse, swfmill)
- Natural Entry Point Method
- LB.Log, Zeroi

Pro, Firefox, Chromium(Iron), IE

----------------
Pro,
Re: swfmillでGIF画像の置換について
 
自分がswfmillを使うのはAS2開発時の画像埋め込みやコンポーネントを使う場合がほとんどで、今回のようなswfmillの使い方がある事を今の今まで知りませんでした(汗)。調べてみるとケータイ用Flashではswfmillを使うのが常識という感じなのですね。

投稿された内容を見るに、「GIF形式から独自形式への変換がPHPで上手くいかない」という事でしょうか?
もしかしたら、その上手くいかなかったPHPコードを載せたりするのも、より的確なアドバイスを得るのに良いかもしれませんね。
…もっとも、自分はPerlをよく使っていてPHPについてよく知らないので、その時は他のかたの投稿を期待する事になるかもしれませんが(汗)。

なので自分は自分で別の方法を考えるべく、あーだこーだ調べてみる事に。
まずは確認のため、画像ファイルを表示するだけのものをswfmillで作りました。

※各ファイルのパスは省略しています

【application.xml】

<?xml version="1.0" encoding="utf-8"?>
<movie framerate="24" height="270" version="8" width="360">
    <clip id="image" import="test.jpg" />
    <frame>
        <place id="image" x="0" y="0" depth="0" />
    </frame>
</movie>

【コマンドライン】

swfmill simple application.xml application.swf

できあがったapplication.swfを実行してみると、確かに埋め込んだJPEG形式の画像が表示されています。
続いてPNG形式(24bit)でやってみても問題なく表示され、GIF形式では「WARNING: Cannot import test.gif (unknown extension), skipping.」のメッセージがでて、SWFファイルはできるものの表示が空っぽなのが確認できました。

もしGIFが埋め込み可能だったら、変換作業をswfmillにしてもらえばいいかなと思ったからなのですが、これは少し残念です。
しかしPNGは大丈夫という事から、GIFをいったんPNGに変換し、それを埋め込めばいいかもしれないと思いました。実際に試していないので上手くいくか分かりませんが、次のような感じで変換コードを自分で書かずとも、GIF画像の置き換えができるかもしれません。

(1) メインで使うSWFファイルを「swfmill swf2xml」コマンドでXMLファイルに変換

(2) 置き換え用のGIFファイルをPNGファイル(24、32bit)に変換

(3) (2)の埋め込みを記述したXMLから「swfmill simple」でSWFを作成

(4) (3)を「swfmill swf2xml」でXMLに変換して、その中から画像データを取り出す

(5) (1)の中の画像データを(4)に置き換えて、「swfmill xml2swf」でSWFに変換

なんだかサーバーリソースの無駄づかいといった感じですが(汗)、PHPのコードはこれらの処理をまとめてあげるだけなので、そのぶん簡単そうです。PNG形式への変換については、ImageMagickやGDといったライブラリがPerlにはあるのですが、PHPにもそういった画像関係のライブラリがあれば手軽に変換できるかもしれません。

さらに検索していると、SWFToolsに含まれている gif2swf が使えるかもしれないという事が分かりました。これならGIFからSWFに直接変換できるので、上記(2)(3)(4)を一つにできてもっと楽になれそうです(SWFToolsはLinux用もあります)。


----------------
:961832p:
- だんだんAS3に慣れてきた“なんちゃって”AMES使いの日曜プログラマー

takemaru
Åê¹ÆNo.45019
投稿日時: 2010-5-26 20:57
新米
居住地:
投稿: 6
使用環境:
Re: swfmillでGIF画像の置換について
961832pさん、アドバイスありがとうございます。
また、確認までして頂きましてありがとうございます。

こちらで行いたいGIFファイルの置換について、説明を追加させて頂きます。

?GIFが埋め込まれているFLASHテンプレートがあります。
 ※埋め込んでいるGIF画像ファイルは別途あります。
?埋め込まれているGIF画像と動的に作成するGIF画像を置換する。
 ※置換するファイルの縦×横は同じサイズの画像です。
?置換対象のSWFフォーマットは、DefineBitsLosslessとなります。
?swfmill、SWFEditor、GD、ImageMagic、SWFToolsなど使用可能なLinux環境です。

※GIF画像にした理由は、メモリ消費軽減、ファイルサイズ軽減、画質がJPGより良いことです。
※swfmillの派生ツールのSWFEditorで、JPG、PNG画像の置換は確認きましたが、GIFはできませんでした。

▼テンプレートFLASH画像をXML化した一部分の内容
引用:
<?xml version="1.0" encoding="UTF-8"?>
<swf version="4" compressed="0">
※省略
  <DefineBitsLossless objectID="5" format="3" width="400" height="110">
   <data>
    <data>AXja7cFBEQAADAIg+5fWW4s9gPQEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHhnxnwT8</data>
   </data>
  </DefineBitsLossless>
※省略
  <DefineBitsLossless objectID="8" format="3" width="35" height="110">
   <data>
    <data>AXja7cExAQAADAIg+5d2ltgHNJ0AAAAAbw4umQT8</data>
   </data>
  </DefineBitsLossless>
※省略


GIF画像は、
「AXja7cExAQAADAIg+5d2ltgHNJ0AAAAAbw4umQT8」
このように変換された文字列データになっています。
この文字列データから画像抽出ができたり、埋め込んでいる画像ファイルから同様の文字列データに変換できるような処理を調査しております。
※両方とも単色のGIF画像ファイルになります。

アドバイス頂いた方法についてはあまり確認できていないのですが、SWFToolsを使って埋め込んでいる画像をSWF化して文字列データを確認したら、
「/3ic7cExAQAADMOg+DfdmdgJVNsCAAAAgFcHOlUC/g==」
という違った文字列データになってしまいました。
これで同様の文字列データになってくれれば問題解決だったので、かなり期待したのですが、意気消沈中です。

また、何かわかりましたらご報告させて頂きます。
961832p
Åê¹ÆNo.45043
投稿日時: 2010-5-27 19:18
常連
居住地: Akiruno-shi
投稿: 155
使用環境:
 
:AS3:
- Adobe Flex SDK, Eclipse, AIR GEAR
- LB.Log AS3, Alcon2

:AS2:
- AMES(ASDT, MTASC, Eclipse, swfmill)
- Natural Entry Point Method
- LB.Log, Zeroi

Pro, Firefox, Chromium(Iron), IE

----------------
Pro,
Re: swfmillでGIF画像の置換について
 
takemaru さん、応答ありがとうございます。

同じGIF画像が、作成ツールの違いで埋め込みデータも違ってしまうのは確かに気になりますね。
なので自分も100ピクセル四方の白地に、赤青緑3つの四角が並んだGIFファイルを用意して試してみました。

 ・Adobe Flash を使い、GIFファイルを貼り付けてパブリッシュしたSWF
 ・SWFToolsのgif2swfを使い、GIFファイルから変換したSWF

これら2つのSWFファイルをswfmillでXMLに変換して中を見てみると、確かに画像データ部分が違っている事を確認しました。
また、実際に表示してみるとgif2swfを使ったSWFはナゼか緑色の四角だけ黒になっていたので、画像データが何かしら変化しているもようです。これはGIFファイルによって変わってくるのかもしれません。

置き換えるGIF画像は動的生成という事なので、前述のPNGに変換する方法では無駄が多いでしょうし、やっぱりPHPで変換コードを組まねばならない感じになるのでしょうか。う?む。

その後もあーだこーだ検索していると、関係ありそうなPHPのライブラリがありました。

 ・Image Converter (swf, convert, animated GIF, ming) - PHP Classes

ここはユーザー登録しないとダウンロードできないですし、ライセンスについても「Freeware」としか書かれていないので、詳しくは本体ファイルを見ないと分かりませんが、このライブラリを使っているかたのサンプルコードを見ると、なんだか出来そうな雰囲気が感じられます。
あくまで雰囲気だけですので、全く関係の無いライブラリかもしれないです(汗)。


----------------
:961832p:
- だんだんAS3に慣れてきた“なんちゃって”AMES使いの日曜プログラマー

takemaru
Åê¹ÆNo.45061
投稿日時: 2010-5-28 19:19
新米
居住地:
投稿: 6
使用環境:
Re: swfmillでGIF画像の置換について
961832pさん、確認及びアドバイスありがとうございます。

 ・Image Converter (swf, convert, animated GIF, ming) - PHP Classes

⇒ 確認してみようと、ユーザー登録してダウンロードしてみました。ソースを確認してみると、
タイトルにも記載がありますが、Ming関数を使用してSWF化している感じでした。
当方の環境にMing関数がインストールされていなかったので、インストールし確認してみたのですが、
どうもうまく動作しない状況です。

「PHPのMingが正常に動作しない」みたいな記事を見掛けたりしましたが、関係あるのでしょうか。。。。

処理を要約すると以下のような事をしています。

引用:

$image = imageCreateFromGIF("test.gif");

ob_start();
imagejpeg($image);
$buffimg = ob_get_contents();
ob_end_clean();

$img = new SWFBitmap($buffimg);

$w = $img->getWidth();
$h = $img->getHeight();

$movie = new SWFMovie();
$movie->setDimension($w, $h);
$movie->add($img);

if($swfname)
 $movie->save($swfname);
else
 $movie->output;


▼エラー箇所:new SWFBitmap($buffimg);
 ⇒ PHP Fatal error: opening bitmap file failed

また、何か分かりましたらご報告いたします。
961832p
Åê¹ÆNo.45082
投稿日時: 2010-5-31 13:29
常連
居住地: Akiruno-shi
投稿: 155
使用環境:
 
:AS3:
- Adobe Flex SDK, Eclipse, AIR GEAR
- LB.Log AS3, Alcon2

:AS2:
- AMES(ASDT, MTASC, Eclipse, swfmill)
- Natural Entry Point Method
- LB.Log, Zeroi

Pro, Firefox, Chromium(Iron), IE

----------------
Pro,
Re: swfmillでGIF画像の置換について
 
takemaru さん、ライブラリを確認していただいてありがとうございます。
Mingの存在についても教えていただき、調べているとPerl用もあったので自分にとって収穫でした。

PHPはよく分かりませんが、投稿されましたコードの大まかな流れを見ているとゼロからSWFを生成している感じで強力そうですね。でもこのMingを使うとなると今までswfmillを使ってきた意味が無くなってしまうような気もしますし…う?む。

なんとなく深みにハマった自分がいますが(汗)、GIFの埋め込みについては何とかしなければいけないので、自分もあと少しだけ調べて必ず報告します!


----------------
:961832p:
- だんだんAS3に慣れてきた“なんちゃって”AMES使いの日曜プログラマー

takemaru
Åê¹ÆNo.45093
投稿日時: 2010-6-2 15:26
新米
居住地:
投稿: 6
使用環境:
Re: swfmillでGIF画像の置換について
961832pさん

こちらこそいろいろと調査ありがとうございます。
アドバイス返信頂けるだけでもありがたいです。

1人だったらとっくに諦めてました

新たにPHPのサンプルソースが見つかり、文字列から画像抽出する方法が分かり
文字列の仕様が完全ではないかもしれませんが、分かったのでご報告いたします。
※不適切な表現などある場合がありますので、ご了承願います。


以下、単色のGIF画像がXML化された際の文字列(※両方とも同じGIF画像データ)
※(ui8dec()、ui16dec()、save_lossless_8()はサンプルライブラリ内の関数となりますので、記載は省略します)

引用:
▼swfmillでXML化した際の文字列
 $fileName = "swfmill.gif";
 $width = 35;
 $height = 110;
 $string = "AXja7cExAQAADAIg+5d2ltgHNJ0AAAAAbw4umQT8";

 $base64Decode = base64_decode($string);
 
 $colorMapCnt = ui8dec($base64Decode[0]) + 1;
 $colorTableCnt = $colorMapCnt * 3; //3=RGB

 $colorMapData = gzuncompress(substr($base64Decode, 1));

 $colorTable = substr($colorMapData, 0, $colorTableCnt);
 $pixelData = substr($colorMapData, $colorTableCnt);

 save_lossless_8($fileName, $pixelData, $colorTable, $width, $height);

引用:
▼サンプルソースで内部生成された文字列をbase64_encodeかけた文字列
 $fileName = "sample.gif";
 $fullString = "CAADIwBuAAF42u3BMQEAAAwCIPuXdpbYBzSdAAAAAG8OLpkE/A==";

 $base64Decode = base64_decode($fullString);

 $bitmap["id"] = ui16dec(substr($base64Decode, 0, 2));
 $bitmap["bitdepth"] = ui8dec($base64Decode[2]);
 $bitmap["bitmap_width"] = ui16dec(substr($base64Decode, 3, 2));
 $bitmap["bitmap_height"] = ui16dec(substr($base64Decode, 5, 2));

 $bitmap["colormap_cnt"] = ui8dec($base64Decode[7]) + 1;
 $bitmap["colormap_data"] = gzuncompress(substr($base64Decode, 8));
 $bitmap["color_table_cnt"] = $bitmap["colormap_cnt"] * 3;

 $bitmap["color_table"] = substr($bitmap["colormap_data"], 0, $bitmap["color_table_cnt"]);
 $bitmap["pixel_data"] = substr($bitmap["colormap_data"], $bitmap["color_table_cnt"]);

 save_lossless_8($fileName, $bitmap["pixel_data"], $bitmap["color_table"], $bitmap["bitmap_width"], $bitmap["bitmap_height"]);


⇒swfmillでは、idや縦×横サイズの情報は付与されていませんでしたが、
 サンプルソースでは、それらが付与される形でデータが生成されてました。
 ※swfmillのバージョンによって文字列データの仕様が異なるかもしれません。

 ⇒swfmillで生成された文字列だけでは、画像は抽出できないようで、他のXML化されたデータから
  縦×横サイズの情報を取得する必要があるようです。

 ⇒上記のような内容で、画像抽出はできました。出力はpngファイルになってます。


本題については別返信で投稿します。


▼画像抽出サンプルソース
http://code.google.com/p/mikrokosmos/source/browse/trunk/php/mk/test/s04_grabbing_images.php?r=2

▼主要関連ソース
http://code.google.com/p/mikrokosmos/source/browse/trunk/php/mk/classes/mk_classes.php?r=2
http://code.google.com/p/mikrokosmos/source/browse/trunk/php/mk/lib/mk_lib_images.php?spec=svn2&r=2
⇒ save_lossless_8()など
http://code.google.com/p/mikrokosmos/source/browse/trunk/php/mk/lib/mk_lib_swf.php?r=2
⇒ ui8dec()、ui16dec()など。
takemaru
Åê¹ÆNo.45095
投稿日時: 2010-6-2 16:41
新米
居住地:
投稿: 6
使用環境:
Re: swfmillでGIF画像の置換について
961832pさん

本題の私が行いたい、「動的に生成するGIF画像を同様の文字列データに変換する」件は
画像抽出ができたので、すぐできるかと思いましたが、無念です。。。
でも、一歩前進です。

私の特定素材で単色GIF画像同士の置換には成功しましたが、汎用的な内容ではありません。
置換したい画像を単色ではなく、本来の複数色の画像ファイルでやろうとすると
画像再抽出した際に、画像が壊れたかたちで表示されます。
置換は一応、壊れたデータで置換はされます。
引用:

 $im = imagecreatefromgif($gifPath);
 $size_x = imagesx($im);
 $size_y = imagesy($im);
 $transId = imagecolortransparent($im);
 $color_map_count = imagecolorstotal($im);

//**************************************
// color数+1する場合の条件があるかも?
//**************************************
 $colorMapNum = $color_map_count + 1;

 /*
  * MAKE COLORMAP
  */
 $colormap = array();
 for ($i=0; $i<$color_map_count; $i++) {
  $v = imagecolorsforindex($im, $i);
  $colormap[] = chr($v['red']);
  $colormap[] = chr($v['green']);
  $colormap[] = chr($v['blue']);
 }

//**************************************
// color数+1のデータ?(No.1)
//**************************************
$colormap[] = chr(255);
$colormap[] = chr(255);
$colormap[] = chr(255);

 /*
  * MAKE INDICES
  */
 $cnt=0;
 $indices_data = array();

 for ($y=0; $y<$size_y; $y++) {
  for ($x=0; $x<$size_x; $x++) {
  $color_index = imagecolorat($im, $x, $y);
  $indices_data[] = chr($color_index);
  }
 }

//**************************************
// color数+1のデータ?(No.2)
//**************************************
for ($y=0; $y<$size_y; $y++) {
$dummy_date[] = chr(0);
}

 /*
  * ENCODE
  */
 $gzcompress = chr($colorMapNum).gzcompress(implode('',$colormap).implode('',$indices_data).implode('',$dummy_date));
 $base64data1 = base64_encode($gzcompress1); //※1

 //**************************************
 //画像抽出処理にて確認(※前回投稿した処理)
 //**************************************
 $base64Decode = base64_decode($base64data1);
 
 $colorMapCnt = ord($base64Decode[0]) + 1;
 $colorTableCnt = $colorMapCnt * 3; //3=RGB

 $colorMapData = gzuncompress(substr($base64Decode, 1));

 $colorTable = substr($colorMapData, 0, $colorTableCnt);
 $pixelData = substr($colorMapData, $colorTableCnt);

 save_lossless_8("test.gif", $pixelData, $colorTable, $size_x, $size_y);

 $gzcompress2 = chr($colorMapCnt).gzcompress($colorTable. $pixelData);
 $base64data2 = base64_encode($gzcompress2); //※2

 $swfmill_str = "AXja7cExAQAADAIg+5d2ltgHNJ0AAAAAbw4umQT8";
 $xmlString = str_replace($swfmill_str, $base64data2, $xmlString); //$xmlStringはswfmillでxml出力した主データ。

※最初の※1で圧縮+エンコードしたデータと、そのデータを一度、非圧縮しデコードし
 また再度、圧縮+エンコード(※2)しても、同じ文字列データにはなりませんでした。

 ※1= "Anic7cExAQAADAIg+5d2ltgHNJ0AAAAAbw4umQT8";
 ※2= "A3ic7cExAQAADAIg+5d2ltgHNJ0AAAAAbw4umQT8";
 ⇒注)swfmillで生成される文字列: "AXja7cExAQAADAIg+5d2ltgHNJ0AAAAAbw4umQT8";

 ⇒詳しい事は分かりませんが、頭から4バイト(文字)が、変化しましたが
  文字列データからの画像の再抽出は問題なくできました。


■今後の課題
 ・colormap数を+1する場合の条件があるかも?について調査
  ⇒単色でも縦×横サイズが大きい画像や、複数色の画像では、「color数+1のデータ?」が不要。
 ・単色ではなく、複数色を使用したGIF画像(写真、イメージ)などの置換方法の調査。
 ・swfmillで生成される文字列と全く同じ文字列を元画像ファイルから生成する方法の調査。
  ⇒現状は、文字列データとしては多少の差異が発生するが、画像データとしては、正常に認識される。
 ・汎用的なプログラム。


と、こんな感じです。
分かりづらい説明で申し訳ありません。
何かご質問などありましたら、バシバシお願いします。
961832p
Åê¹ÆNo.45111
投稿日時: 2010-6-3 19:02
常連
居住地: Akiruno-shi
投稿: 155
使用環境:
 
:AS3:
- Adobe Flex SDK, Eclipse, AIR GEAR
- LB.Log AS3, Alcon2

:AS2:
- AMES(ASDT, MTASC, Eclipse, swfmill)
- Natural Entry Point Method
- LB.Log, Zeroi

Pro, Firefox, Chromium(Iron), IE

----------------
Pro,
Re: swfmillでGIF画像の置換について
 
※このトピックの情報は以降のトピックで上書きされています

takemaru さん、とても重要な情報ありがとうございます!

自分はその後、いちばん最初に投稿されましたリンクの先でRuby製のコードを見つけ、これを参考にPerlでも出来るのかなとあーだこーだ作っていたのでした(今回作ったサンプルコードは末尾にあります)。

とはいえ簡単に出来るであろうはずもなく、自分が作ったもので生成されたデータを埋め込むと、swfmillで変換できるものの真っ赤な四角が表示されるSWFしか生成されないという状況が続いていたのです。
そんな中、昨日の takemaru さんが投稿された情報は自分にとってブレークスルーでありました。

ImageMagickに頼りまくっていますが(汗)、自分も画像からオリジナルと同じデータを生成することが出来るようになりました。
まさか圧縮データの前に付加されていようとは…自分の環境だと、先頭に付加されていたものは「パレット数-1」が入る1Byteぶんのデータのみでした。なぜ1引かねばならないのかは謎ですが、もしかしたら「0からパレット数-1まで」という考え方なのかもしれません。

自環境で確認したswfmill用画像データのフォーマット

 ※パレットデータはRGBの順で並ぶ(各チャンネルは1Byte)
 ※ピクセルデータは幅が4の倍数になるよう毎ライン0でパディングする
 +------------+----------------+--------------+
 |パレット数-1|パレットデータ  |ピクセルデータ|
 |------------+----------------+--------------|
 |1Byte       |パレット数*3Byte|幅*高*1Byte   |
 +------------+----------------+--------------+
  ↓
 +------------+----------------+--------------+
 |未圧縮      |ZLIB                           |
 +------------+----------------+--------------+
  ↓
 +------------+----------------+--------------+
 |Base64                                      |
 +------------+----------------+--------------+

【オリジナルデータ作成に使用した環境】
 Windows XP Pro SP3
 swfmill 0.2.12.2

【オリジナルデータの元となるSWFについて】
 Adobe Flash を使い、GIF画像を1枚貼り付け Flash Player 4 の設定でパブリッシュ
 他のオプションはデフォルトのまま

上記フォーマットに従って生成したデータを埋め込んでSWFにすると画像は正しく表示されるようになりましたが、オリジナルのXMLにあるデータと文字列が違っています。
あーだこーだ試していると、Adobe Flash ではパブリッシュすると画像データのパレット数を2の累乗数に揃えている事が分かりました(27色なら32色、49色なら64色となった)。不足分のパレットはパレットデータの後ろへ0でパディングされているようです。

この処理をやらなくても画像は正しく表示されますしデータサイズも僅かに減って有利ですが、この処理を加える事で完全にオリジナルと同じデータとなりました。
また、ZLIBは圧縮レベルを最大の9にして圧縮している事も分かりました(他のレベルだと同じ文字列にならない事から)。

自環境だとswfmillで変換されるXMLデータにはn_colormap属性が付かないので、それを補うため先頭に使用パレット数が分かるデータが必要なのでしょうが、どんな場合に先頭へ付加されるデータが変わるのか、それが分かれば汎用性のあるものが出来そうですね。
swfmillはソースコードが公開されているので、そのへんの手がかりがあるのかもしれませんが、チョロっと見た感じではXSLTでCのソースコードを生成しているらしく、処理を追うのは時間がかかりそうかなと思いました(汗)。

と、現状はこんな感じでしょうか。これらが何かしらの手がかりになると良いのですが。
takemaru さんの情報のおかげで、あの真っ赤な四角を見続ける悶々とした状況から抜け出せたので嬉しい限りです。

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

以降は今回作ったサンプルに関するものです。サンプルコード内では、データ生成に関係しない部分は色を薄くしています。

 ・データ生成テストCGI ※ページ上部に広告がでます
 ・オリジナルSWFをswfmillで変換したXMLファイル

test.cgiの中身

use strict;
use MIME::Base64;
use Compress::Zlib;
use Image::Magick;

##24ビットカラーへ戻すためのビット移動量
my $SHIFT_DEPTH = Image::Magick->QuantumDepth - 8;
##読み込むファイル
my $path_image = "./test_c49.gif";
##パレット&ピクセルデータ格納用
my $data = q{};

#
##画像の読み込み&各情報を取得
##
my $image = Image::Magick->new;
$image->Read($path_image);
my ( $width, $height, $colors ) = $image->Get( "width", "height", "colors" );

#
##パレットデータを格納
##
my $pallett = [];
for ( my $i = 0 ; $i < $colors ; $i++ ) {
    my ( $r, $g, $b, $x ) = split ",", $image->Get("colormap[$i]");
    $data .= pack "CCC", $r >> $SHIFT_DEPTH, $g >> $SHIFT_DEPTH, $b >> $SHIFT_DEPTH;
    ##後で表示用に使うために
    push @{$pallett},
      {
        "red"   => $r >> $SHIFT_DEPTH,
        "green" => $g >> $SHIFT_DEPTH,
        "blue"  => $b >> $SHIFT_DEPTH,
      };
}
##パレットを Adobe Flash に合わせる場合は2の累乗数に揃える(元の値よりも小さくしない)
##この処理をしない場合 → my $colors_now = $colors;
##テーブルやループを使わないで計算する方法はあるのかな?
my @ppow_conv = ();
my $ppow      = 1;
for ( my $i = 0 ; $i < 256 ; $i++ ) {
    $ppow_conv[$i] = $ppow;
    $ppow <<= 1 if $ppow == $i;
}
my $colors_now = $ppow_conv[$colors];
##足りないぶんを詰めもの
$data .= pack( "CCC", 0, 0, 0 ) x ( $colors_now - $colors );

#
##ピクセルデータを格納
##
my @pixels = ();
my $padding = pack( "C", 0 ) x ( 4 - $width & 3 );
for ( my $y = 0 ; $y < $height ; $y++ ) {
    for ( my $x = 0 ; $x < $width ; $x++ ) {
        my $index = $image->Get("index[$x,$y]");
        $data .= pack "C", $index;
        ##後で表示用に使うために
        push @pixels, $index;
    }
    ##幅ピクセル数が4の倍数になるよう詰めもの
    $data .= $padding;
}

#
##swfmill画像データを生成
##
##追加情報
my $add = q{};
$add .= pack "C", $colors_now - 1;
##注:追加情報にはZLIBをかけない
my $data_swfmill = MIME::Base64::encode( $add . compress( $data, 9 ), q{} );

#
##HTMLで出力
##
print qq{Content-type:text/html\n\n};
##
print qq{<html><head><meta content="text/html; charset=UTF-8" http-equiv="content-type"></head>\n};
print qq{<body style="font-family:monospace; line-height:1.4;">\n};
##各情報を表示
printf qq{<p>[Perlバージョン] %s<br>[ImageMagickバージョン] %s</p>},
  $], $image->Get("version");
printf qq{<p>[ファイル] %s [タイプ] %s [幅] %s [高さ] %s [パレット数] %s -> %s</p>},
  $path_image, $image->Get("magick"), $width, $height, $colors, $colors_now;
##swfmill用画像データを表示
printf qq{<pre>[swfmill用画像データ]<br><input style="width:100%;" type="text" value="%s"></pre>},
  $data_swfmill;
##画像を表示
print qq{<p>[左画像] img要素で表示<br>[右画像] ImageMagickから得たデータを表示(確認用)</p>\n};
print qq{<div style="position:absolute; left:10px; top:330px;"><img src="$path_image" alt=""></div>\n};
print qq{<div style="position:absolute; left:100px; top:330px;">};
my $style = "position:absolute; left:%d; top:%d; width:1px; height:1px; background-color:rgb(%d,%d,%d);";
for ( my $i = 0 ; $i < scalar @pixels ; $i++ ) {
    my $index = $pixels[$i];
    printf qq{<span style="$style"></span>},
      $i % $width, sprintf( "%d", $i / $width ),
      $pallett->[$index]{"red"}, $pallett->[$index]{"green"}, $pallett->[$index]{"blue"};
}
print qq{</div>\n};
##
print qq{</body></html>\n};

__END__


----------------
:961832p:
- だんだんAS3に慣れてきた“なんちゃって”AMES使いの日曜プログラマー

takemaru
Åê¹ÆNo.45142
投稿日時: 2010-6-7 17:07
新米
居住地:
投稿: 6
使用環境:
Re: swfmillでGIF画像の置換について
961832pさん、こちらこそ重要な情報ありがとうございます。

引用:
・Adobe Flash ではパブリッシュすると画像データのパレット数を2の累乗数に揃えている事が分かりました(27色なら32色、49色なら64色となった)。
 ※不足分のパレットはパレットデータの後ろへ0でパディングされているようです。
・ピクセルデータは幅が4の倍数になるよう毎ライン0でパディングする
・ZLIBは圧縮レベルを最大の9にして圧縮している

こちらの情報とサンプルソースを元に確認したところ、swfmillがGIF画像をxml化する際に生成する文字列と同様の文字列生成に成功しました!!。 :
ただ、上記の赤字の箇所、「不足分のパレットを0でパディングする」ということでしたが、
私が確認していたSWF&単色画像素材では、255でパディングすることで、完全一致の文字列生成ができました。
もちろん、0でパディングしての文字列生成及び生成文字列からの画像抽出、swfmillでの画像置換などは問題なくできました。
※961832pさんが確認に使用している素材でこちらでも確認しましたが、確かに0でパディングで完全一致しました。
この違いについての要因は、分かっていません。

引用:
まさか圧縮データの前に付加されていようとは…自分の環境だと、先頭に付加されていたものは「パレット数-1」が入る1Byteぶんのデータのみでした。なぜ1引かねばならないのかは謎ですが、もしかしたら「0からパレット数-1まで」という考え方なのかもしれません。

こちらについては、以下のページに「色テーブルに使用する色の数 - 1。最大 256 色。」と説明されていました。
http://hkpr.info/flash/swf/index.php?%E3%83%93%E3%83%83%E3%83%88%E3%83%9E%E3%83%83%E3%83%97%2FDefineBitsLossless

961832pさんのおかげで目的達成できそうです!!
本当にありがとうございました。

以下に、PHP版のお粗末なサンプルコードで失礼しますが載せておきます。
引用:
 $padKbn = 1;
 $imgSizeInfo = getimagesize($filePath);

 $im = imagecreatefromgif($filePath);
 $size_x = $imgSizeInfo[0]; 
 $size_y = $imgSizeInfo[1]; 
 $colorCount = imagecolorstotal($im);

 //********************************************************************
 // パレットデータ生成
 //********************************************************************
 $pallett = array();
 for ($i=0; $i<$colorCount; $i++) { 
  $v = imagecolorsforindex($im, $i); 
  $pallett[] = pack('C', $v['red']); 
  $pallett[] = pack('C', $v['green']);
  $pallett[] = pack('C', $v['blue']);
 }

 $ppow = 1;
 for ($i = 0 ; $i < 256 ; $i++ ) {
  if($i == 1){
   $ppow_conv[$i] = 2;
  }else{
   $ppow_conv[$i] = $ppow;
  }
  ( $ppow == $i ) ? $ppow <<= 1 : "";
 }

 $colors_now = $ppow_conv[$colorCount];

 //********************************************************************
 // パレット補正データ付加※0or255
 //********************************************************************
 $padPallettCnt = $colors_now - $colorCount;

 for($i=0;$i<$padPallettCnt;$i++){
  if($padKbn == 1){
   $pallett[] = pack('C', 0); 
   $pallett[] = pack('C', 0); 
   $pallett[] = pack('C', 0); 
  }else{
   $pallett[] = pack('C', 255);
   $pallett[] = pack('C', 255);
   $pallett[] = pack('C', 255);
  }
 }

 //********************************************************************
 // ピクセル補正データ取得
 //********************************************************************
 $padPixelCnt = ( 4 - $size_x & 3);

 $padPixel = "";
 for($i=0;$i<$padPixelCnt;$i++){
  $padPixel[] = pack('C', 0);
 }

 //********************************************************************
 // ピクセルデータ生成
 //********************************************************************
 $indices_data = array();

 for ($y=0; $y<$size_y; $y++) { 
  for ($x=0; $x<$size_x; $x++) { 
   $color_index = imagecolorat($im, $x, $y);
   $indices_data[] = pack('C', $color_index); 
  }
  
  if(empty($padPixel) == FALSE){
   $indices_data = array_merge($indices_data, $padPixel);
  }
 }

 //********************************************************************
 // 圧縮&エンコード
 //********************************************************************
 $gzcompress = pack('C', $colors_now-1).gzcompress(implode('',$pallett).implode('',$indices_data), 9);
 $base64data = base64_encode($gzcompress);
(1) 2 »
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 
Copyright (C) 2003 FLASH-japan. All rights reserved.
Powered by Xoops