[ 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 へとレイヤ構造を保ったまま持っていくことが可能である。
レイヤ構造と言えば 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 へとレイヤ構造を保ったまま持っていくことが可能である。
コメント
コメントを投稿