[英]Image PropertyItems and disposed MemoryStream
我正在使用MemoryStream
從byte[]
加載一個Image
,並通過檢查它的ProperyItems
獲取有關該圖像的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
的內容支持,解決方案不是處理它,或者我錯了?
在調試此問題的過程中,盡管我注意到了其他一些奇怪的問題,但是如果我訪問using
塊內的PropertyIdList
(或與圖像PropertyItems
相關的任何內容),則在處理MemoryStream
之后, PropertyItems
不會消失。
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
數據的本地副本,那么為什么在這種情況下處理MemoryStream
之后PropertyItems
保留?
一般來說,處理MemoryStream是一件相當無用的事情。 它本身沒有任何可使用的資源,僅是內存,已經由垃圾收集器管理。 僅當您使用了BeginRead / Write()方法並且它們尚未完成(這是您永遠不會做的事情)時才重要。
但它確實將CanRead()屬性設置為false。 這對你從MemoryStream加載的Bitmap對象非常致命。
接下來,當你繼續使用Bitmap時,會發生什么是相當不可預測的。 GDI +要求流保持可讀的,它可在以后使用,讀取惰性方式的位圖數據。 最典型的情況是,當位圖被繪制時,這往往會因“通用錯誤”而相當可靠地使程序崩潰。
你找到了另一個角落案例,似乎只是認為沒有更多的屬性。 否則,這並不是那么神秘,您確實關閉了流,因此不再有可能讀取的屬性。 對於GDI +而言,它不會產生異常,但這並不常見。
只是擺脫使用聲明,它沒有做任何有用的事情。 如果您仍然擔心如何處理流,則必須在不再使用Bitmap對象之后再進行處理。
因為創建的img2
超出了using
語句的范圍,所以處理流不會影響它。
PropertyIdList
是Image而不是MemoryStream
對象的方法。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.