如何从 System.Drawing.Bitmap 对象中提取原始图像流?
我使用 .resx
文件将图像嵌入到程序集中。运行时,我需要将图像保存到独立文件中,恢复原始内容。如何从 System.Drawing.Bitmap 实例中提取原始文件流?我知道我可以使用 Bitmap.Save() 创建流,但这会转码(实际上是膨胀)图像,即使将 PNG 保存回 PNG 也是如此。
或者也许我的错误是首先从 Resource
中将它们读取为 Bitmap
?
I am embedding images into my assembly using .resx
files. Upon runtime, I need to save the images into standalone files, restoring the original content. How can I extract the original file stream from an System.Drawing.Bitmap
instance? I know I can create a stream using Bitmap.Save()
, but this transcodes (and in effect - inflates) the images, even when saving a PNG back as PNG.
Or perhaps my mistake is reading them from Resource
as Bitmap
in the first place?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
是的,一旦您将其作为 Bitmap 对象读取,您就无法取回原始文件流。
Bitmap
对象仅包含未压缩的数据,而不包含原始数据。您应该将资源读取为字节数据。您可以从资源流中读取数据并写入文件:
注意:这需要将图像添加为嵌入式资源,而不是托管资源。您可以使用
Image.FromStream()
从它创建一个Image
。Yes, once you have read it as a
Bitmap
object, you can't get the original file stream back. TheBitmap
object only contains the uncompressed data, not the original data.You should read the resource as byte data intead. You can read from the resource stream and write to a file:
Note: this requires adding the image as an embedded resource, not a managed resource. You can create an
Image
from it usingImage.FromStream()
.我不明白这个问题。 PNG 是一种无损格式,您将得到完全相同的图像。是的,当您 Save() 时,您不一定会得到完全相同的字节。它是一种压缩格式,压缩器在压缩和速度之间获得最佳平衡所花费的时间可能不同。但是,那又怎么样?
如果这是一个真正的问题,那么您不应该将图像添加为托管资源。您可以将其作为嵌入式资源添加到项目中,并使用 Assembly.GetManifestResourceStream() 从元数据中读取它。您将获得原始图像文件字节。可使用 Image.FromStream() 转换为图像。
I don't get the problem. PNG is a loss-less format, you'll get the exact same image back. Yes, you don't necessarily get the exact same bytes when you Save(). It is a compressed format and the amount of time spent by the compressor on getting the best balance between compression and speed might not be the same. But, so what?
If it is a real problem then you shouldn't add the image as a managed resource. You can add it to your project as an embedded resource and read it from the metadata with Assembly.GetManifestResourceStream(). You'll get the raw image file bytes. Convertible to an Image with Image.FromStream().
如何:使用 Visual C# 从资源加载位图或图像
HOW TO: Load a Bitmap or Image from a Resource by Using Visual C#
如果您实际上并未将位图用于应用程序中的显示目的(即您只是将资源提取为位图,以便将其保存为文件),那么最简单的方法是只需以
Stream
形式获取资源并将其保存到文件中即可。本教程展示如何以流的形式获取资源:
http://devhood.com/Tutorials/ tutorial_details.aspx?tutorial_id=75
在示例中,作者获取一个流并将其传递给
Bitmap.FromStream
方法。相反,您要做的就是将该流直接保存到文件中(完全绕过Bitmap
)。If you're not actually using the
Bitmap
for display purposes in your appliction (i.e. you're just extracting the resource as a bitmap so you can save it as a file), then the simplest approach is to just get the resource as aStream
and save it to a file.This tutorial shows how to get resources as streams:
http://devhood.com/Tutorials/tutorial_details.aspx?tutorial_id=75
In the sample, the author gets a stream and passes it to the
Bitmap.FromStream
method. What you would do instead is just save that stream directly to a file (bypassingBitmap
entirely).事实证明,问题在于使用托管资源 - resx 生成器从图像文件创建 Bitmap 对象并序列化这些对象,它不存储原始文件流。但是,嵌入式资源可以存储平面二进制文件。
我现在使用以下
.csproj
条目嵌入图像文件夹中的所有文件:Visual Studio 将它们显示为正常的项目内文件,并将
Build Action
设置为Embedded资源
。然后,从我的代码中,我使用以下命令加载原始文件流:
It turns out the problem was in using managed resources - resx builder creates Bitmap objects from image files and serializes those objects, it does not store the original file stream. However, embedded resources can store flat binary files.
I am now embedding all files from my images folder using the following
.csproj
entries:Visual Studio shows them as normal in-project files with
Build Action
set toEmbedded Resource
.Then, from my code, I load the original file streams with: