Visual C++によるSWFファイル作成

ほうほうサイト作品を拝見し、元がペーパーアニメでAVIなFlashも割と現実的な容量で、しかも見るに耐える画質を得られることが分かりました。
そこでTMS2AVIでSWFを出力しようと思いちょっと調査してみました。
ちなみにSWFというのは、macromediaFlashの使う映像フォーマットです。
Mingという出力用ライブラリがある模様。

目次

  1. Mingのダウンロード
  2. VC++によるlibming.libのビルド
  3. VC++によるサンプルのビルド
  4. 問題点
  5. 謎のdbl
  6. 関連リンク

Mingのダウンロード

Ming - an SWF output library and PHP moduleから、0.2aをダウンロードしました。
srcの下がlibmingのソース。linux一辺倒な感じだけれどまぁ仕方ないですね。

VC++によるlibming.libのビルド

まずはSilent Hummingぷにぷにのメモ: Win32でJaMingをビルドに書かれている通り(以下引用)
・ファイル内のinlineを__inlineに置換
 (VCでinlineが使えるのはC++のみ) 
・shape_cubic.cのインクルードファイルに"libming.h"を追加。 
します。
んで、氏のように必要なファイルをリストアップしてVC++のプロジェクトを作成しても良いのですが、面倒な人はこのVC++用makeファイルをsrc直下に置いて、コンソールから
>nmake -f libming.mak
を実行します。型が違う旨の警告が山程出ますが、一応libming.libが作成される筈です。
コンソールからnmakeが使えないって人はVC++をMSDOSプロンプトから使うを参照して下さい。

VC++によるサンプルのビルド

なんか、mingpp.hがコンパイルエラーを起こすので、とりあえずstring.hをインクルードして、630行目付近を
//  void addString(const char *string, float *advance=NULL)
//    { SWFText_addString(this->text, string, advance); }
  void addString(const char *string, int *advance=NULL)
    { SWFText_addString(this->text, string, advance); }
に修正。floatをintに修正したけれど、本当にこれで良いのかは不明。調査が必要なんだけど、 多分tms2aviではこの関数使わないので放置。 そのうち本家が修正するでしょう。
で、このVC++用メイクファイルをc++_extに置いて
>nmake -f test.mak
出来たtest.exeをコマンドプロンプトから実行すると、何だか謎の化け化け文字列が出ます。これは添付されてるサンプルがサーバサイドでの利用を前提に標準出力にswfを吐くためです。
最後の
movie->output();
 を
movie->save( "test.swf");
にすると、test.swfというswfファイルが作られるようになります。ちなみにIEで表示すると白地に黒い四角が描かれるだけです。ピクリとも動きません。
余り面白く無いので次に Silent HummingCでMingのサンプルをC++にしてみました。で、メイクファイル
実行するとblink.swfが出力され、これは緑の四角形が明滅しながら回転する映像でして眺めて綺麗です。
つか、なんかMingってLGPLということで改変版を公開したらソースも提供しなきゃならんようなので、全部まとめてこれ
でもソースは本家から取った方がいいと思うけど…。makファイル、サンプルは役に立つかも。もっともlibming.makはこれもどっかのNGから見つけたものですけど。元記事が見付からないのですが。

問題点

さて、tms2aviは、ビットマップをアニメのセル画のように重ねて映像ファイルにします。
おそらくSWFBitmapを使いまくる筈です。 で、SWFBitmap とfclose の罠Re: SWFBitmap とfclose の罠という記事を発見。消えると困るので以下一部引用です。
ming 0.2a では、jpeg Bitmap を add するとき、
fclose のタイミングによっては SWF の出力に失敗するみたいです。

失敗する例:
#include 
main()
{
  SWFMovie m;
  SWFBitmap b;
  FILE *fp = NULL;

  fp = fopen("test.jpg", "rb");
  
  m = newSWFMovie();
  b = newSWFJpegBitmap(fp);

  SWFMovie_add(m, b);
  
  fclose(fp);  /* <-- ここで close すると save できない */
  SWFMovie_save(m, "test.swf");

  return 0;
}

fclose を save の後で実行すれば大丈夫です。僕はかなり悩みました。
http://www.opaque.net/pipermail/ming-fun/2001-January/000068.html
を見つけて、ようやく気がつきました。

池上です。

同様に alpha mask のために開く mask file も fclose すると
SWFMovie_save のときに Bus Error で落ちるようです。

Ming のソースを眺めましたが、
SWFInput が file pointer を握っているのが前提になっているみたいなので、
2, 3 行直すだけでは回避できそうにないです…
むぅ。まずいです。100フレーム出力するならファイルを100個開いたまま?1000フレームだと同時に1000?駄目じゃん。
ていうか、同じことで困ってる方が。ぬぅ。

謎のdbl

Mingで読み込めるビットマップはJPEGとDBLなる謎の画像フォーマット。透明度付きらしい。PNGは駄目なのか…。
tms2aviで連番DBL出力とか思いつくけど、それをやると当然Mingソースの流用する場面が出てきて、tms2avi本体がGPLに感染してしまう…。 tms2aviのソースは私の他のソフトのあちこちで共有とか流用してるから、全部GPLに感染?
libmingに勝手にたとえばdbl出力関数、というようなものを追加してDLLとして隔離、本体からはこれを呼び出すって形にすればOKなのだろうか。
とりあえず触らぬGPLに祟り無しなのでやめとこ。

関連リンク

という訳で、Mingはイマイチ使えない事が分かった。
だが、まだまだその他重要なFlash関連技術(動的生成、SWF等)があるので何れまたトライしてみようと思う。



フリーソフトウェアへ戻る
ホームページへ戻る
お手紙はnekora@mapletown.netまで☆