WPF、前回の64bppとかの画像ファイルを読み込んでPixelFormatを確認してみた
前回は画像のPixelFormatをいろいろ変更してファイルに保存した
正しく保存されていないのもあったけど、それは置いといて
今回はこのファイルを、いくつかの方法で読み込んで
PixelFormatやbpp(ビットの深さ)を確認してみた
この画像ファイルのビットの深さは64のpngファイル
ビットの深さ(色深度)
色の深さ64なら64bppとか64bitとかもたぶん同じ意味
このファイルを読み込んでBitmapSourceにしてみる
4つの方法で試した
//方法1
//BitmapImageから作成
private BitmapSource Test(string filePath)
{
return new BitmapImage(new Uri(filePath));
}
//方法2
//BitmapFrameから作成
private BitmapSource Test2(string filePath)
{
return BitmapFrame.Create(new Uri(filePath));
}
//方法3
//BitmapDecoderから作成
private BitmapSource Test3(string filePath)
{
BitmapDecoder decoder =
BitmapDecoder.Create(
new Uri(filePath),
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.OnLoad);
return decoder.Frames[0];
}
//方法4
//FileStreamとBitmapDecoderから作成
private BitmapSource Test4(string filePath)
{
BitmapDecoder decoder;
using (FileStream fs = new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
decoder = BitmapDecoder.Create(
fs,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.OnLoad);
}
return decoder.Frames[0];
}
2018/01/14修正
方法3と方法4の赤文字のところ
BitmapCacheOption.Default);を
BitmapCacheOption.OnLoad);に
修正
期待するのはPixelFormatはRgba64でビットの深さは64bppの
BitmapSourceが取得できること
結果
方法1から3だと
PixelFormatはPbgra32でbppは32になっている、違う、そうじゃない
期待どおりだったのは方法4だけだった
PixelFormatはRgba64でbpp(BitsPerPixel)が64で期待どおり!
方法4とそれ以外の違いはFileStream使用の有無
方法2のBitmapFrameはFileStreamからも作成できるので、これを書き換えて
方法2’
//BitmapFrameから作成、FileStreamを使う方法
private BitmapSource Test2(string filePath)
{
//return BitmapFrame.Create(new Uri(filePath));
BitmapFrame frame;
using (FileStream fs =
new FileStream(filePath, FileMode.Open, FileAccess.Read))
{
frame = BitmapFrame.Create(fs,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.OnLoad);
}
return frame;
}
2018/01/14修正
赤文字のところ
BitmapCacheOption.Default);を
BitmapCacheOption.OnLoad);に
修正
こうしてみたらこれでも正しく読み込めた!
なのでファイルのフォーマットどおりに読み込みたいときは、FileStreamを使えばいいみたい
方法4と方法2’を比べるとラクそうなのは方法2’かな
FileStreamがいまいちよくわかっていないのと
BitmapFrame.Createの引数のBitmapCreateOptionsとBitmapCacheOptionもぜんぜんわからん
前回の
24bppのjpegファイルをBgr32のBitmapSourceとして読み込んで
PixelFormatをいろいろ変更して画像ファイルとして保存
ファイルのプロパティに表示されるビットの深さ、bpp一覧
↑のこれらを方法1から3で読み込んだ結果一覧が
↓
一致しないのが多けど
普通の画像なら32bpp以下だからこれでも問題ないんだよねえ
Cmyk32ってのがよくわかんない
4色でそれぞれ8bitだから合計32bitならいいのかなあ
次は
方法4で読み込んだ結果一覧
かなり改善された!
とくにwdp形式はかなり正確になっている
bmpのdefaultってのは説明を読んでもわからなかったけど64bppだった
追記2018/01/14
BitmapCreateOptions.PreservePixelFormat
っていうのを使ったから正確になったみたいで
【C#】画像ファイルのカラーモードを判断する方法 - Sweets Junkieこちらが参考になりました、ありがとうございます
http://sweets-junkie.hatenablog.com/entry/2014/03/12/053024
BitmapCreateOptions.PreservePixelFormatを指定しないと
自動で最適なPixelFormatに変更されてしまうみたい
確かに今の環境では32bpp以上あってもほとんど無意味だからねえ
追記ここまで
bppとパレットの色数一覧
PixelFormats クラス (System.Windows.Media)
https://msdn.microsoft.com/ja-jp/library/system.windows.media.pixelformats(v=vs.110).aspx
確認のために作ったアプリ
方法1から3で確認
Rgb128FloatなのにBgr32で取得されている
方法4と方法2’
正確に取得できている
いろいろなbpp(ビットの深さ)のpngを投稿してみる
1bpp
BlackWhite.png
Indexed1.png
2bpp
Gray2.png
Indexed2.png
4bpp
Gray4.png
Indexed4.png
8bpp
Gray8.png
Indexed8.png
32bpp
Bgra32.png
これが一番普通だと思います
48bpp
Rgb48.png
64bpp
Prgba64.png
2018/01/14修正した箇所の
frame = BitmapFrame.Create(fs,
BitmapCreateOptions.PreservePixelFormat,
BitmapCacheOption.OnLoad);
これね、赤文字のところ
修正前はDefaultにしていた、もう一度試していたらエラーが出るようになっていたので、色々いじってOnLoadにしたらエラーにならず画像も表示された
けどなんでこれいいのか全然わかっていない
BitmapCacheOption 列挙型 (System.Windows.Media.Imaging)
より引用
Default
イメージ全体をメモリにキャッシュします。 これが既定値です。
None
メモリ保存は作成しないでください。 イメージのすべての要求はイメージ ファイルから直接入力されます。
OnDemand
要求されたデータに対してのみ、メモリ保存を作成します。 最初の要求で、イメージが直接読み込まれます。後続の要求はキャッシュから入力されます。
OnLoad
読み込み時にイメージ全体をメモリにキャッシュします。 イメージ データのすべての要求はメモリ保存から入力されます。
引用ここまで
説明読んでも理解できないゾw
2018/01/14追記ここまで
とある無職の悪戦記録: C#で64bitPNG64bitのpngを作成している方がいらっしゃいました!すごい!
http://hima-tubusi.blogspot.jp/2017/09/c64bitpng.html
前回の記事は2日前
WPF、PixelFormatを変更した画像をファイルに保存、FormatConvertedBitmap ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15320177.html
2日後
WPF、画像ファイルを開く方法まとめ ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15325331.html