2011-06-30 22 views
1

我有一個「ImageManipulator」類,用於在iPhone上執行一些裁剪,調整大小和旋轉相機圖像。在iPhone上調整圖像大小,旋轉和裁剪圖像時內存消耗會增加

目前,一切都按預期工作,但我不斷收到一些內存消耗的巨大峯值,偶爾會導致應用程序崩潰。

我已經設法將問題隔離到代碼的一部分,我檢查當前的圖像方向屬性並將其相應地旋轉到UIImageOrientationUp。然後,我從位圖上下文中獲取圖像並將其保存到磁盤。

這是目前我在做什麼:

CGAffineTransform transform = CGAffineTransformIdentity; 
// Check for orientation and set transform accordingly... 
transform = CGAffineTransformTranslate(transform, self.size.width, 0); 
transform = CGAffineTransformScale(transform, -1, 1); 

// Create a bitmap context with the image that was passed so we can perform the rotation 
CGContextRef ctx = CGBitmapContextCreate(NULL, self.size.width, self.size.height, 
             CGImageGetBitsPerComponent(self.CGImage), 0, 
             CGImageGetColorSpace(self.CGImage), 
             CGImageGetBitmapInfo(self.CGImage)); 

// Rotate the context 
CGContextConcatCTM(ctx, transform); 

// Draw the image into the context 
CGContextDrawImage(ctx, CGRectMake(0,0,self.size.height,self.size.width), self.CGImage); 

// Grab the bitmap context and save it to the disk... 

即使試圖縮小圖片到一半甚至1/4大小,我仍然看到了尖峯我以後想知道是否有是一種不同的/更有效的方式來完成上述的旋轉?

在此先感謝您的回覆。 Rog

+0

圖像有多大?我們有類似的問題,所以我們首先將圖像縮放到可接受的尺寸,然後應用旋轉。 –

+0

您是否在冗長的操作中創建大型自動釋放對象? – Eiko

+2

內存尖峯是因爲'CGBitmapContextCreate'必須分配一個緩衝區來保存圖像數據,這將是關於'width * height * CGImageGetBitsPerComponent(self.CGImage)/ 8'字節。如果需要在繪製原始圖像之前加載或解壓縮原始圖像的圖像數據,'CGContextDrawImage'也可能分配另一個相似大小的緩衝區。不過,我不知道更有效的方法。 – Anomie

回答

1

如果您要保存爲JPEG格式,我想另一種方法是按原樣保存圖像,然後通過操縱EXIF元數據將旋轉設置爲任何您想要的值。見例如this post。簡單但可能有效,即使你必須在內存中保存圖像有效負載字節)

0
  • 您是否嘗試過檢查內存泄漏並分析分配?
  • 如果圖像仍然太大,請嘗試將圖像分片而不是整體旋轉。
-1

由於Anomie提到,CGBitmapContextCreate創建了一個上下文。我們應該通過使用釋放

CGContextRelease(ctx); 

如果您有使用創建或複製創建的任何其他對象,也應該釋放。如果是CFData,然後

CFRelease(cfdata); 
1

事情可以做:

  1. 比例縮小的圖像更(你可能不希望)

  2. 記住釋放一切,一旦你完成它

  3. 住它

我會選擇選項2和3

圖像編輯非常耗費資源,因爲它加載整個原始未壓縮的圖像數據轉換成用於處理內存。這是不可避免的,因爲除了將完整的原始數據加載到內存之外,絕對沒有其他方式來修改映像。除非應用程序收到內存警告,否則內存消耗尖峯並不重要,在這種情況下,在崩潰之前快速清除所有內容。但是,很少會發生內存警告,因爲我的應用程序會定期將單個> 10 MB的文件加載到內存中,即使在較舊的設備上,我也不會收到警告。所以你會很好的尖峯。

相關問題