ログイン
メインメニュー
|
投稿者 |
スレッド |
961832p |
Åê¹ÆNo.45160 投稿日時: 2010-6-8 20:03 |
常連 居住地: 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 さん、返答ありがとうございました。ひとまず成功されたようで自分も嬉しいです。
引用:ただ、上記の赤字の箇所、「不足分のパレットを0でパディングする」ということでしたが、 私が確認していたSWF&単色画像素材では、255でパディングすることで、完全一致の文字列生成ができました。 もちろん、0でパディングしての文字列生成及び生成文字列からの画像抽出、swfmillでの画像置換などは問題なくできました。 ※961832pさんが確認に使用している素材でこちらでも確認しましたが、確かに0でパディングで完全一致しました。 この違いについての要因は、分かっていません。 表示に影響は無いとはいえ、気になったので自分も試してみる事に。 その結果、勘違いしている事がありました。自分はてっきりパレットデータのパディング処理は Adobe Flash がパブリッシュ時にやっているものだと思っていたのですが、よく見るとGIF画像ファイルの時点で既にパディングされていました(汗)。
試しにFireWorksやGIMP等いくつかのソフトでGIF画像を作ってみると確かにパディングデータが255のものもあり、ソフトによって違ってくるのかもしれません。GIFのフォーマット仕様書は見ていないので不確かですが、2の累乗数にパディングする事は決まっていても、中の値は決まってないという事なのかなと思いました。
ImageMagickが返すパレット数は実際に使われているパレット数だったようで、すっかり勘違いしていたのですが、幸いにもパディングデータを含む全パレットデータはImageMagickで取得できるようで、それを使うように処理の順番を少し変えてみました。
自環境で確認しただけなので、これらは普遍なものなのか微妙なところですが、これなら0と255をフラグで切り替えなくても大丈夫かもしれないと思いました。
----------------
以降は今回作ったサンプルに関するものです。データ生成部分はCGIと分離してあります。
・テストCGI ※ページ上部に広告がでます
【test_new.cgi】
use strict;
##swfmill用画像データ生成プログラムのパス
my $path_call = "./gif_to_definebitslossless_format3_for_swfmill.pl";
##GIF画像ファイルのパス
my @path_image = ( "./test_c32.gif", "./test_c49.gif" );
##
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};
##GIFファイルから生成されたswfmill用画像データを表示
foreach my $arg (@path_image) {
##パイプから受け取る
open my $fh, "perl $path_call $arg |" or die;
binmode $fh;
my $swfmill_data = join q{}, <$fh>;
close $fh;
##
printf qq{<p>元画像:%s<br>swfmill用画像データ:%s<br>%s</p>\n},
qq{<a href="$arg">$arg</a>},
qq{<input style="width:75%;" type="text" value="$swfmill_data">},
qq{<a href="$arg.swf.xml">オリジナルのXMLファイル</a>};
}
##
print qq{</body></html>\n};
__END__
【gif_to_definebitslossless_format3_for_swfmill.pl】
use strict;
use MIME::Base64;
use Compress::Zlib;
use Image::Magick;
##24ビットカラーへ戻すためのビット移動量
my $SHIFT_DEPTH = Image::Magick->QuantumDepth - 8;
##読み込むファイルパス(引数から)
my $path_image = shift @ARGV;
##パレット&ピクセルデータ格納用
my $data = q{};
#
# 画像の読み込み&各情報を取得
##
my $image = Image::Magick->new;
$image->Read($path_image);
my ( $width, $height, $colors ) = $image->Get( "width", "height", "colors" );
#
# パレットデータを格納
##(注)Image::MagickのGet("colors")は、実パレット数を返すもよう
##なので現在より大きく、かつ2の累乗数にして全てのパレット情報を得る
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 = $colors;
my $colors_now = $ppow_conv[$colors];
##
for ( my $i = 0 ; $i < $colors_now ; $i++ ) {
my ( $r, $g, $b, $x ) = split ",", $image->Get("colormap[$i]");
$data .= pack "CCC", $r >> $SHIFT_DEPTH, $g >> $SHIFT_DEPTH, $b >> $SHIFT_DEPTH;
}
#
# ピクセルデータを格納
##
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;
}
##幅ピクセル数が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{} );
##
print "$data_swfmill\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%2FDefineBitsLossless961832pさんのおかげで目的達成できそうです!! 本当にありがとうございました。 以下に、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);
|
|
|
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.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で生成される文字列と全く同じ文字列を元画像ファイルから生成する方法の調査。 ⇒現状は、文字列データとしては多少の差異が発生するが、画像データとしては、正常に認識される。 ・汎用的なプログラム。 と、こんな感じです。 分かりづらい説明で申し訳ありません。 何かご質問などありましたら、バシバシお願いします。
|
|
|
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=2http://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()など。
|
|
|
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.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.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.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.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使いの日曜プログラマー
|
|
|
|
|