2

次のC#コードを使用して、(一部の内部HDRデータから)Format48bppRgb.PNGファイルを作成することができました。

Bitmap bmp16 = new Bitmap(_viewer.Width, _viewer.Height, System.Drawing.Imaging.PixelFormat.Format48bppRgb);
System.Drawing.Imaging.BitmapData data16 = bmp16.LockBits(_viewer.ClientRectangle, System.Drawing.Imaging.ImageLockMode.WriteOnly, bmp16.PixelFormat);
unsafe {  (populates bmp16) }
bmp16.Save( "C:/temp/48bpp.png", System.Drawing.Imaging.ImageFormat.Png );

ImageMagik(および他のアプリ)は、これが実際に16bppの画像であることを確認します。

C:\temp>identify 48bpp.png
48bpp.png PNG 1022x1125 1022x1125+0+0 DirectClass 16-bit 900.963kb

しかし、PNGを読み戻すと、次のコマンドを使用すると、Format32bppRgbに変換されていたことがわかりました。

Bitmap bmp = new Bitmap( "c:/temp/48bpp.png", false );
String info = String.Format("PixelFormat: {0}", bmp.PixelFormat );
...

PNGコーデックがFormat48bppRgbを書き込むことができるとすると、変換せずに.NETを使用して読み取る方法はありますか?DrawImage呼び出しでこれを実行してもかまいませんが、ヒストグラム/画像処理作業のために、解凍された元のデータにアクセスしたいと思います。

4

2 に答える 2

5

参考までに - System.Windows.Media.Imaging を使用してこれに対する .NET ソリューションを見つけました (私は厳密に WinForms/GDI+ を使用していました - これには WPF アセンブリを追加する必要がありますが、機能します)。失われた情報:

using System.Windows.Media.Imaging; // Add PresentationCore, WindowsBase, System.Xaml
...

    // Open a Stream and decode a PNG image
Stream imageStreamSource = new FileStream(fd.FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
PngBitmapDecoder decoder = new PngBitmapDecoder(imageStreamSource, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.Default);
BitmapSource bitmapSource = decoder.Frames[0];

    // Convert WPF BitmapSource to GDI+ Bitmap
Bitmap bmp = _bitmapFromSource(bitmapSource);
String info = String.Format("PixelFormat: {0}", bmp.PixelFormat );
MessageBox.Show(info);

...

そして、次のコード スニペット: http://www.generoso.info/blog/wpf-system.drawing.bitmap-to-bitmapsource-and-viceversa.html

private System.Drawing.Bitmap _bitmapFromSource(BitmapSource bitmapsource) 
{ 
    System.Drawing.Bitmap bitmap; 
    using (MemoryStream outStream = new MemoryStream()) 
    { 
        // from System.Media.BitmapImage to System.Drawing.Bitmap 
        BitmapEncoder enc = new BmpBitmapEncoder(); 
        enc.Frames.Add(BitmapFrame.Create(bitmapsource)); 
        enc.Save(outStream); 
        bitmap = new System.Drawing.Bitmap(outStream); 
    } 
    return bitmap; 
} 

WPF を必要としないこれを行う方法を誰かが知っている場合は、共有してください。

于 2011-09-01T22:49:20.830 に答える
2

Image.FromFile(String, Boolean)または_Bitmap.FromFile(String, Boolean)

ブール値を true に設定します。すべての画像プロパティが新しい画像に保存されます。

ここで文字列はフルパスのファイル名です...

画像が既にプログラムにロードされていて、それを使用して新しいビットマップを作成する場合は、次を使用することもできます

MemoryStream ms = new MemoryStream();
img.Save(ms, ImageFormat.Bmp); // img is any Image, previously opened or came as a parameter
Bitmap bmp = (Bitmap)Bitmap.FromStream(ms,true);

一般的な代替手段は

Bitmap bmp = new Bitmap(img); // this won't preserve img.PixelFormat
于 2012-07-10T05:13:19.473 に答える