Loading an image from a stream without keeping the stream open(从流加载图像而不保持流打开)
问题描述
是否可以使用 System.Drawing.Image 的 FromStream 方法而不必在图像的生命周期内保持流打开?
Is it possible to use the FromStream method of System.Drawing.Image without having to keep the stream open for the lifetime of the image?
我有一个应用程序,它使用 Image.FromStream
和 Assembly.GetManifestResourceStream
.
I have an application which loads a bunch of toolbar graphics from resource files, using a combination of Image.FromStream
and Assembly.GetManifestResourceStream
.
我遇到的问题是,虽然这在 Windows 7 上运行良好,但在 Windows XP 上,如果链接到这些图像之一的用户界面元素被禁用,应用程序就会崩溃.在 Windows 7 上,图像以灰度呈现.在 XP 上,它会因内存不足异常而崩溃.
The problem I'm having is while this works fine on Windows 7, on Windows XP the application crashes if a user interface element linked to one of these images is disabled. On Windows 7, the image is rendered in grayscale. On XP, it crashes with an out of memory exception.
经过一番拉扯,我终于将其追溯到图像的初始加载.当然,如果我创建任何实现了 IDisposable
的对象,并且在同一方法中也被销毁,我会将它包装在 using 语句中,例如
After a load of hairpulling I have finally traced it to the initial loading of the image. As a matter of course, if I create any object implementing IDisposable
that is also destroyed in the same method, I wrap it in a using statement, for example
using (Stream resourceStream = assembly.GetManifestResourceStream(resourceName))
{
image = Image.FromStream(resourceStream);
}
如果我删除 using 语句以便不处理流,则应用程序在 XP 上不再崩溃.但是我现在有一堆孤立"流挂在周围 - 图像存储在命令类中,当它们自己被处理时,这些图像会正确地处理图像,但原始流不是.
If I remove the using statement so that the stream isn't disposed, then the application no longer crashes on XP. But I now have a bunch of "orphan" streams hanging about - the images are stored in command classes and these correctly dispose of the images when they themselves are disposed, but the original stream isn't.
我查看了 FromStream
并确认流需要保持打开状态.然而,为什么这在 Windows 7 开发系统上没有崩溃和烧毁是一个谜!
I checked the documentation for FromStream
and it confirms the stream needs to remain open. Why this hasn't crashed and burned on the Windows 7 development system is a mystery however!
我真的不希望这个流四处闲逛,而且我当然不想必须存储对这个流的引用以及图像,以便我以后可以处理它.我只需要一次该流,所以我想摆脱它:)
I really don't want this stream hanging around, and I certainly don't want to have to store a reference to this stream as well as the image so I can dispose of it later. I only have need of that stream once so I want to get rid of it :)
是否可以创建图像然后在那里杀死流?
Is it possible to create the image and then kill of the stream there and then?
推荐答案
需要打开流的原因是 以下:
The reason the stream needs to be open is the following:
GDI+ 以及 System.Drawing 命名空间可能会推迟原始图像位的解码,直到图像需要这些位.此外,即使在图像已被解码后,GDI+ 也可能确定丢弃大位图的内存并稍后重新解码更有效.因此,GDI+ 必须在 Bitmap 或 Image 对象的生命周期内访问图像的源位.
GDI+, and therefore the System.Drawing namespace, may defer the decoding of raw image bits until the bits are required by the image. Additionally, even after the image has been decoded, GDI+ may determine that it is more efficient to discard the memory for a large Bitmap and to re-decode later. Therefore, GDI+ must have access to the source bits for the image for the life of the Bitmap or the Image object.
已记录的解决方法是使用 Graphics.DrawImage
创建非索引图像,或从原始图像创建索引 Bitmap
,如下所述:
The documented workaround is to create either a non-indexed image using Graphics.DrawImage
or to create an indexed Bitmap
from the original image as described here:
位图和图像构造函数依赖
这篇关于从流加载图像而不保持流打开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:从流加载图像而不保持流打开
基础教程推荐
- 如何使用OpenXML SDK将Excel转换为CSV? 2022-01-01
- Page.OnAppearing 中的 Xamarin.Forms Page.DisplayAlert 2022-01-01
- 我什么时候应该使用 GC.SuppressFinalize()? 2022-01-01
- C# - 将浮点数转换为整数...并根据余数更改整数 2022-01-01
- 从 VB6 迁移到 .NET/.NET Core 的最佳策略或工具 2022-01-01
- C# - 如何列出发布到 ASPX 页面的变量名称和值 2022-01-01
- 使用 SED 在 XML 标签之间提取值 2022-01-01
- 覆盖 Json.Net 中的默认原始类型处理 2022-01-01
- 当键值未知时反序列化 JSON 2022-01-01
- 创建属性设置器委托 2022-01-01