WPF、Tiff画像の圧縮形式とファイルサイズ、TiffBitmapEncoderのCompress
今までは何も指定しないで作成していたけど圧縮(エンコード)方式をいくつか選べるみたいなので試してみた
TiffBitmapEncoder.Compression プロパティに
TiffCompressOption列挙型から選んで指定する
TiffCompressOption 列挙型 (System.Windows.Media.Imaging)
から引用
Ccitt3引用ここまで
CCITT3 圧縮スキーマが使用されます。
Ccitt4
CCITT4 圧縮スキーマが使用されます。
Default
TiffBitmapEncoder エンコーダーは、実行できる最適な圧縮スキーマで、ビットマップを保存しようとしています。
Lzw
LZW 圧縮スキーマが使用されます。
None
Tagged Image File Format (TIFF) イメージは圧縮されません。
Rle
RLE 圧縮スキーマが使用されます。
Zip
Zip 圧縮スキーマが使用されます。
何も指定しないとDefaultになる
圧縮する画像は
圧縮方式による見た目の違い
Ccitt3 14.2
Ccitt4 14.4
Default 128
Lzw 170
None 144
Rle 145
Zip 132
圧縮なのにLzwとRleは元画像よりファイルサイズが増えている
一番効率がいいのはDefaultなので何も指定しないのがいいみたい
Defaultの説明では最適な圧縮方法を採りますってあるけどなんだろうって気になる
エクスプローラーのファイルのプロパティから見ると
LZWってある
でもLzwを指定してできたファイルとはサイズが違いすぎる
ファイルのプロパティから見た圧縮方式
指定した単語とは微妙に違ったり表示がなかったり
でもDefaultとLzwはどちらもLZWだねえ
TIFFファイルの圧縮フォーマット判別法こちらを参考にして
http://robaq.info/tiffcompression.xhtml
バイナリエディタで確認してみた
先頭2バイトが49 49なら
検索で03 01 03 00 01 00
これで見つかった場所から12バイト分の後の4バイトの値が、5なら圧縮方式はLZWってことらしい
DefaultもLzwも5
だけどLzwを指定したものは170KBってぜんぜん違うサイズだからなあ
LZWにも種類があるってことかしら
これ以上は難しそうなのでパス
別の画像を圧縮
ファイルサイズ変化 画像A 画像B KB KB 元画像 144 990 Ccitt3 14 31 Ccitt4 14 41 Default 128 107 Lzw 170 93 None 144 769 Rle 145 575 Zip 132 46
おお、スゴイ縮んだ
Defaultでも10分の1に圧縮できているし、一番効率が良かったZip形式では20分の1
可逆圧縮でこの圧縮率はスゴイ
今回参照したところ
TiffCompressOption 列挙型 (System.Windows.Media.Imaging)ありがとうございます
https://msdn.microsoft.com/ja-jp/library/system.windows.media.imaging.tiffcompressoption(v=vs.110).aspx
TIFFファイルの圧縮フォーマット判別法
http://robaq.info/tiffcompression.xhtml
CGファイル概説 第5章 第2節 その2
http://www.snap-tck.com/room03/c02/cg/cg05_03.html
TIFFのフォーマット(その1) | JProgramer
http://jprogramer.com/libtiffcate/3188
TIFF Tag Reference, Baseline TIFF Tags
https://www.awaresystems.be/imaging/tiff/tifftags/baseline.html
TIFF - Wikipedia
https://en.wikipedia.org/wiki/TIFF
画像ファイルパスからBitmapSourceを作成
TiffBitmapEncoderのFrameにそれを入れて
Compressに圧縮形式を指定してからファイルに保存しているだけ
今回はXAML必要なかった、こういう時にコンソールアプリってのがあるんだろうなあ
画像ファイルパスからBitmapSource作成の
GetBitmapSource10は前回の記事
TiffBitmapEncoderにFrame追加は
encoder.Frames.Add(取得したBitmapSource);
これだとエラーになったので
取得したBitmapSourceからBitmapFrame.Createで作成したものを追加で
BitmapFrame frame = BitmapFrame.Create(取得したBitmapSource);
encoder.Frames.Add(frame);
こうした
2018/01/17修正
int stride = (w * pixelFormat.BitsPerPixel) / 8;
↑を↓に書き直した
int stride = (w * pixelFormat.BitsPerPixel + 7) / 8;
これで8bpp以下で縦横ともに8の倍数じゃない画像でもエラーにならない
2018/01/21
byte pixels = new byte[w * stride];
↑を↓に書き直した
byte pixels = new byte[h * stride];
前回の記事は1日前
WPF、画像ファイルを開く方法まとめ ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15325331.html
次回は1日後
WPF、wdp画像ファイル作成時の画質設定とファイルサイズ、WmpBitmapEncoder ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15328411.html