簡體   English   中英

圖像PropertyItems和已處置的MemoryStream

[英]Image PropertyItems and disposed MemoryStream

我正在使用MemoryStreambyte[]加載一個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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM