在.NET 中读取/保存 PixelFormat.Format48bppRgb PNG 位图?

发布于 2024-12-02 10:37:30 字数 950 浏览 2 评论 0原文

我已经能够使用以下 C# 代码创建 Format48bppRgb .PNG 文件(来自一些内部 HDR 数据):

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 调用执行此操作,但我想访问解压缩的原始数据以进行某些直方图/图像处理工作。

I've been able to create a Format48bppRgb .PNG file (from some internal HDR data) using the the following C# code:

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 (and other apps) verify that this is indeed a 16bpp image:

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

I was disappointed, however, to find that on reading the PNG back in, it had been converted to Format32bppRgb, when using:

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

Given that the PNG codec can write a Format48bppRgb, is there any way I can use .NET to read it in without the conversion? I don't mind if it does this for a DrawImage call, but I would like access to the decompressed, original data for some histogram/image processing work.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

陪你搞怪i 2024-12-09 10:37:30

仅供参考 - 我确实使用 System.Windows.Media.Imaging 找到了一个 .NET 解决方案(我一直严格使用 WinForms/GDI+ - 这需要添加 WPF 程序集,但有效。)有了这个,我得到了 Format64bppArgb PixelFormat,所以没有丢失信息:

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 的方法,请分享!

FYI - I did find a .NET solution to this using System.Windows.Media.Imaging (I had been using strictly WinForms/GDI+ - this requires adding WPF assemblies, but works.) With this, I get a Format64bppArgb PixelFormat, so no lost information:

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);

...

And this code snippet from: 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; 
} 

If anyone has knows of a way to do this that doesn't require WPF, please share!

我不吻晚风 2024-12-09 10:37:30

使用 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

Use Image.FromFile(String, Boolean) or Bitmap.FromFile(String, Boolean)

And set the Boolean value to true. All image properties will be saved in the new image.

Here String is the filename with full path...

If the image is already loaded in a program and you want to create a new Bitmap with it, you can also use

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);

Common alternative is

Bitmap bmp = new Bitmap(img); // this won't preserve img.PixelFormat
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文