[ C# ] 複数ページからなる TIFF ファイルの作成方法

諸事情により、レイヤ構造を持つ画像ファイルを C# より出力する必要が出てきました。
レイヤ構造と言えば Photoshop の .psd フォーマットが身近で良いのですが、C# の標準ライブラリではサポートしてない為、他のフォーマットを探さないといけません。幸いな事に TIFF はマルチフレーム対応だし、C# の標準ライブラリもマルチフレーム対応との事なので、こちらのページ(http://csharper.blog57.fc2.com/blog-entry-158.html)や、こちらのページ(http://www.bobpowell.net/generating_multipage_tiffs.htm)を参考にプログラムを作ってみました。

どうも MemoryStream の後処理か何かが悪いのか、僕のプログラムだと複数画像を生成すると OutOfMemory が出てしまうので、メモリストリームは使わない方法で作ってみました。

実際のコードからエッセンスだけ抜き出すとこんな感じです(ところで Blogger でソースコードを綺麗に表示するのはどうすれば良いのだろうか?):

// ベース画像と生成した画像からなる 2 フレームの TIFF ファイルを n 個作る。
for(int i=0; i<n; i++) {
    Console.Write("processing "+i+" ...");
    string tiffImagePath=@"baseImage";
    tiffImagePath+=i.ToString("00")+".tif";
    int imageWidth;
    if(File.Exists(tiffImagePath)==false) { continue; }
    Bitmap tiffImage=new Bitmap(tiffImagePath);


    imageWidth=tiffImage.Width;
    Bitmap upperImage=genImage(imageWidth); // 何か絵を作る

    // TIFF エンコーダの取得
    ImageCodecInfo[] imageEncoders=ImageCodecInfo.GetImageEncoders();
    Predicate<ImageCodecInfo> tiffEncoderPredicate

        =delegate(ImageCodecInfo inImageCodecInfo) {
            return inImageCodecInfo.FormatID==ImageFormat.Tiff.Guid;
    };
    ImageCodecInfo tiffEncoder=Array.Find(imageEncoders,

                                          tiffEncoderPredicate);
 

    // エンコーダのパラメータ設定
    EncoderParameters tiffEncoderParameters=new EncoderParameters(2);
    tiffEncoderParameters.Param[0]=new EncoderParameter(
        Encoder.SaveFlag,(long)EncoderValue.MultiFrame
    );
    tiffEncoderParameters.Param[1]=new EncoderParameter(

        Encoder.Compression,(long)EncoderValue.CompressionLZW
    );

    tiffImage.Save("genImage"+i.ToString("00")+".tif",

                   tiffEncoder,tiffEncoderParameters);
 

    // 2ページ目以降の保存に使用するエンコーダのパラメータ。
    EncoderParameters secondPageEncoderParameters

        =new EncoderParameters(2);
    secondPageEncoderParameters.Param[0]

        =new EncoderParameter(Encoder.SaveFlag,
                              (long)EncoderValue.FrameDimensionPage);
    secondPageEncoderParameters.Param[1]

        =new EncoderParameter(Encoder.Compression,
                              (long)EncoderValue.CompressionLZW);

    tiffImage.SaveAdd(upperImage,secondPageEncoderParameters);
    EncoderParameters finishParams=new EncoderParameters(1);
    finishParams.Param[0]

        =new EncoderParameter(Encoder.SaveFlag,
                              (long)EncoderValue.Flush);
    tiffImage.SaveAdd(finishParams);


    Console.WriteLine(" done.");
}



とまぁ、こんな感じで複数ページからなる TIFF ファイルを C# から出力する事ができます。
Windows フォトビューワで開くとちゃんと「2 の 1 ページ」と表示されます。

しかし…Photoshop CS5.1 では複数ページからなる TIFF はサポートしていないのであった。とほほ。


2013 年 1 月 30 日追記
実は複数ページからなる TIFF ファイルは GIMP にて、それぞれのページをレイヤとして読み込むことが出来るようだ。さらに GIMP では Photoshop の .psd 形式での出力もサポートされている為、GIMP 経由で Photoshop へとレイヤ構造を保ったまま持っていくことが可能である。

コメント

このブログの人気の投稿

メモ: ffmpeg を用いた連番ファイルへの変換方法

連番 PPM から FFMpeg と huffyuv でロスレス動画作ってみたんだけど…