午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

WPF、前回の64bppとかの画像ファイルを読み込んでPixelFormatを確認してみた

前回は画像のPixelFormatをいろいろ変更してファイルに保存した
正しく保存されていないのもあったけど、それは置いといて
今回はこのファイルを、いくつかの方法で読み込んで
PixelFormatやbpp(ビットの深さ)を確認してみた
 
イメージ 1
 
この画像ファイルのビットの深さは64のpngファイル

 
ビットの深さ(色深度)
色の深さ64なら64bppとか64bitとかもたぶん同じ意味
イメージ 2
 
 ファイルのプロパティ
このファイルを読み込んで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だと
イメージ 3
PixelFormatはPbgra32でbppは32になっている、違う、そうじゃない
 
 
期待どおりだったのは方法4だけだった
イメージ 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一覧
イメージ 5
 
↑のこれらを方法1から3で読み込んだ結果一覧が
イメージ 21
一致しないのが多けど
普通の画像なら32bpp以下だからこれでも問題ないんだよねえ
Cmyk32ってのがよくわかんない
4色でそれぞれ8bitだから合計32bitならいいのかなあ
 
次は
方法4で読み込んだ結果一覧
イメージ 22
かなり改善された!
とくに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とパレットの色数一覧
イメージ 6

 
WPFのPixelFormats
PixelFormats クラス (System.Windows.Media)
https://msdn.microsoft.com/ja-jp/library/system.windows.media.pixelformats(v=vs.110).aspx
 
 
 
 
確認のために作ったアプリ
方法1から3で確認
イメージ 7
Rgb128FloatなのにBgr32で取得されている
 
方法4と方法2’
イメージ 8
正確に取得できている
 
 
いろいろなbpp(ビットの深さ)のpngを投稿してみる
 
1bpp
イメージ 9
BlackWhite.png
 
イメージ 13
Indexed1.png
 
 
2bpp
イメージ 10
Gray2.png
 
イメージ 14
Indexed2.png
 
 
4bpp
イメージ 11
Gray4.png
 
イメージ 15
Indexed4.png
 
 
8bpp
イメージ 12
Gray8.png
 
イメージ 16
Indexed8.png
 
 
32bpp
イメージ 17
Bgra32.png
これが一番普通だと思います
 
 
48bpp
イメージ 18
Rgb48.png
 
 
64bpp
 
イメージ 19
Prgba64.png
 
 
イメージ 20
Rgba64.png
 
前回は32bppのjpegを投稿したら変な色になったけど
64bppや48bppの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追記ここまで
 
 
 
64bpp pngとかでググっていたら
とある無職の悪戦記録: C#で64bitPNG
http://hima-tubusi.blogspot.jp/2017/09/c64bitpng.html
64bitのpngを作成している方がいらっしゃいました!すごい!
 
 
 
前回の記事は2日前
WPF、PixelFormatを変更した画像をファイルに保存、FormatConvertedBitmap ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15320177.html
 
2日後
WPF、画像ファイルを開く方法まとめ ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15325331.html