gpt4 book ai didi

c# - 图像 PropertyItems 和处置的 MemoryStream

转载 作者:行者123 更新时间:2023-11-30 19:42:00 25 4
gpt4 key购买 nike

我正在加载 Image来自byte[]使用 MemoryStream并通过检查图像的 ProperyItems 获取有关图像的信息.不过,在这样做的过程中,我注意到一些奇怪的行为,其中一些图像的 PropertyItems正在消失。经过多次调试,我终于发现这是由 MemoryStream 引起的。正在处置。

MemoryStream ms0 = new MemoryStream(imageBytes);
Image img0 = Image.FromStream(ms0);
Console.Out.WriteLine("Without using, Image propertyIDs: ");
foreach (int itemId in img0.PropertyIdList)
Console.Out.Write(itemId + ", ");
Console.Out.Write("\n");

Image img1 = null;
using (MemoryStream ms1 = new MemoryStream(imageBytes))
{
img1 = Image.FromStream(ms1);
}
Console.Out.WriteLine("Outside using, Image propertyIDs: ");
foreach (int itemId in img1.PropertyIdList)
Console.Out.Write(itemId + ", ");
Console.Out.Write("\n");

输出:

Without using, Image propertyIDs: 
254, 256, 257, 258, 259, 262, 269, 273, 274, 277, 278, 279, 282, 283, 284, 296,
Outside using, Image propertyIDs:
254, 256, 257, 258, 259, 262, 274, 277, 278, 284, 296,

所以看起来至少有一些 PropertyItems MemoryStream 的内容直接支持解决方案不是处置它,还是我错了?

在调试这个问题的过程中,如果我访问 PropertyIdList,我注意到其他一些奇怪的事情(或与图像 PropertyItems 相关的任何内容)在 using 内 block ,PropertyItemsMemoryStream 之后不会消失已处置。

Image img2 = null;
using (MemoryStream ms2 = new MemoryStream(imageBytes))
{
img2 = Image.FromStream(ms2);
int[] tmp = img2.PropertyIdList;
}
Console.Out.WriteLine("Outside using with PropertyIdList access, Image propertyIDs: ");
foreach (int itemId in img2.PropertyIdList)
Console.Out.Write(itemId + ", ");
Console.Out.Write("\n");

输出:

Outside using with PropertyIdList access, Image propertyIDs: 
254, 256, 257, 258, 259, 262, 269, 273, 274, 277, 278, 279, 282, 283, 284, 296,

我查看了 Image 的来源类和 PropertyIdList属性似乎没有保留 PropertyItems 的本地副本数据,那么为什么 PropertyItems MemoryStream 后保留这种情况怎么处置?

最佳答案

处理 MemoryStream 通常是一件相当无用的事情。它本身没有任何一次性资源,它只是内存,并且已经由垃圾收集器管理。仅当您使用了 BeginRead/Write() 方法并且它们尚未完成时才重要,这是您永远不会做的事情。

但是它确实将 CanRead() 属性设置为 false。这对您从 MemoryStream 加载的 Bitmap 对象来说是非常致命的。

当您继续使用 Bitmap 时,接下来会发生什么,是相当不可预测的。 GDI+ 要求流保持可读,稍后可能会使用它,以惰性方式读取位图数据。最典型的情况是当位图被绘制时,这往往会使您的程序相当可靠地崩溃并出现“一般错误”。

你发现了另一个极端情况,似乎它只是认为没有更多的属性。这并不是那么神秘,您确实关闭了流,因此它无法读取更多属性。它不会为此生成异常是草率的,但对于 GDI+ 来说并不少见。

只是去掉 using 语句,它没有做任何有用的事情。如果您担心无论如何要处理流,那么您必须在您不再使用 Bitmap 对象之后这样做。

关于c# - 图像 PropertyItems 和处置的 MemoryStream,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18215610/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com