2011-08-22 65 views
2

我有一個Windows應用程序項目,處理圖像編輯(裁剪&調整大小)。不幸的是,這些圖像處理消耗了大量的內存和CPU資源(很容易達到600MB或50%的CPU),它只是裁剪和調整一個重量爲2.5MB(2300×5400像素)的gif圖像。不僅如此,由於大量的資源消耗,該程序被卡住而調整...C#:如何減少使用位圖時的內存和CPU消耗?

public static Image Resize(Image imgToResize, Size size) 
    { 
     Bitmap b = new Bitmap(size.Width, size.Height); 
     Graphics g = Graphics.FromImage((Image)b); 
     g.InterpolationMode = InterpolationMode.Default; 
     g.SmoothingMode = SmoothingMode.HighSpeed; 
     g.PixelOffsetMode = PixelOffsetMode.Default; 
     g.DrawImage(imgToResize, 0, 0, size.Width, size.Height); 
     g.Dispose(); 

     return (Image)b; 
    } 

    public static Image Crop(Image img, Point p1, Point p2) 
    { 
     Rectangle cropArea = new Rectangle(p1.X, p1.Y, p2.X - p1.X, p2.Y - p1.Y); 
     return (img as Bitmap).Clone(cropArea, img.PixelFormat); 
    } 

我應該用什麼樣的方法來避免這種情況? 我已經嘗試將它壓縮到內存流中的幾種格式,但它並沒有幫助(甚至使情況變得更糟)

注意:我使用標準的.NET繪圖庫:System.Drawing,System.Drawing.Imaging

回答

3

您的代碼正在創建映像的副本,因此您應該在調用這些方法時期待非託管內存使用率上升。重要的是你對原件做什麼。你擺脫它是明智的,所以它不再佔用內存。你必須調用它的Dispose()方法來做到這一點。等待垃圾收集器做這件事需要很長時間。 Bitmap類只佔用很少的託管內存,但佔用非託管內存。

0

這是一個棘手的問題,也是我之前遇到的問題之一。您可以根據文件大小將映像分成x個部分,然後將每個映像保存到磁盤以確保內存清潔。

接下來,您每次調整一個組件圖像的大小,每次都要確保組件在進入下一個組件之前被丟棄。一旦你完成了,你將它們縫合在一起,然後裁剪。這種方法的一個主要問題 - 如果你調整向上,這種方法將在你的圖像接縫,因爲插值將不會有周圍的像素猜測。但我認爲這種方法可以很好地適應下調尺寸。

HTH。

0

再次另一個提示:

例如,在調整大小,像@Hans指出,創建新的位圖,哪一個是你的瓶頸。

但是,如果你只是圖像大小,它最初加載相同的圖像(很明顯,你之前在磁盤上進行原始圖像的備份文件)。

裁剪後如果你只是用戶裁剪位圖的一部分,所以用戶將只看到該矩形。 ?

我的意思是一般情況下,對已有的圖像進行操作,並嘗試(儘可能多地)不爲其初始化新對象。

問候。

-2

寫入應用程序。的DoEvents();在你的功能,至少它不會卡住

相關問題