前回は画像の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
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追記ここまで
とある無職の悪戦記録: C#で64bitPNG64bitのpngを作成している方がいらっしゃいました!すごい!
http://hima-tubusi.blogspot.jp/2017/09/c64bitpng.html
前回の記事
WPF、PixelFormatを変更した画像をファイルに保存、FormatConvertedBitmap ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15320177.html