swfimagedump
Sazesaki さんの記事(id:sasezaki:20090913)を真似して
swfimagedump を書いてみました。
Jpeg に加えて Lossless 画像が png ファイルに落ちます。
<?php if ($argc < 2) { fprintf(STDERR, "Usage: swfimagedump <swf_file>\n"); exit(1); } $swf_filename = $argv[1]; $swfdata = file_get_contents($swf_filename); $obj = new SWFEditor(); if ($obj->input($swfdata) == false) { fprintf(STDERR, "input failed\n"); exit(1); } $tags = $obj->getTagList(); foreach ($tags as $k => $tag) { $tagName = $tag['tagName']; if (strncmp($tagName, 'DefineBitsJPEG', 14) == 0) { $detail = $obj->getTagDetail($k); $imageId = $detail["image_id"]; file_put_contents($imageId.'.jpg', $obj->getJpegData($imageId)); } elseif (strncmp($tagName, 'DefineBitsLossless', 18) == 0) { $detail = $obj->getTagDetail($k); $imageId = $detail["image_id"]; file_put_contents($imageId.'.png', $obj->getPNGData($imageId)); } }
Iterator に慣れてない古い人間なので、とりあえず foreach してます。
実は、自分で作っておきながら getTagList の戻り値が foreach 出来るの知りませんでしたw
Sazesaki さん有難う御座います。\(^O^)/
備考
あと、SWF ファイルから画像を抜き出すときの注意なのですけど、
実は少なくとも DefineBitsLossless2 についてαチャネルに半透明(0 より
大きく 255 より小さな値)のデータを含む場合、厳密には原理的に元画像を
復元するすべがありません。
仕様書(swf spec ver10 の p154)によると、
BitmapPixelData ARGB[image data size] Array of pixel colors.
Number of entries is BitmapWidth * BitmapHeight. The RGB data
must already be multiplied by the alpha channel value.
なんだそうです。割った数をかけても元に戻りません。
詳しくは以前書いた日記で ↓
- id:yoya:20090215