2014-10-07 129 views
2

我一直在努力解決這個問題的過去3天,我不明白爲什麼/如何解決我的內存警告/由於圖像過濾崩潰。GPU內存崩潰與GPUImage

就這麼簡單:用戶可以選擇不同的過濾器,然後保存圖片。

我有不同的問題,我設法克服,這裏是我的最終代碼(我刪除了一切不重要的地方)。

- (void)viewDidLoad{ 

// Setting up the filter chain, it's better to do it now to avoid lags 
// if we had done it in the "filter" methods, about 3 sec lag. 

    stillImageSource = [[GPUImagePicture alloc]initWithImage:_photo]; 
    GPUImageBrightnessFilter *soft; 
    GPUImageContrastFilter *medium; 
    soft = [[GPUImageBrightnessFilter alloc]init]; 
    medium = [[GPUImageContrastFilter alloc]init]; 
    soft.brightness = -0.5; 
    medium.contrast = 1.6; 
} 
- (IBAction)mediumFilter:(id)sender { 

    [stillImageSource addTarget:medium]; 
    [medium useNextFrameForImageCapture]; 
    [stillImageSource processImage]; 

    //[medium endProcessing]; // Not sure what this does but i've seen it around. 

    [self.imgPicture setImage:[medium imageFromCurrentFramebuffer]]; 
    [stillImageSource removeAllTargets]; 
} 

- (IBAction)denseFilter:(id)sender { 

    [stillImageSource addTarget:soft]; 
    [soft addTarget:medium]; 
    [medium useNextFrameForImageCapture]; 
    [stillImageSource processImage]; 

    //[soft endProcessing]; 
    //[medium endProcessing]; // Not sure what this does but i've seen it around. 

    [self.imgPicture setImage:[medium imageFromCurrentFramebuffer]]; 
    [stillImageSource removeAllTargets]; 

} 

- (IBAction)softFilter:(id)sender { 

    [stillImageSource addTarget:soft]; 
    [soft useNextFrameForImageCapture]; 
    [stillImageSource processImage]; 

    //[soft endProcessing]; 

    [self.imgPicture setImage:[soft imageFromCurrentFramebuffer]]; 
    [stillImageSource removeAllTargets]; 


} 

用戶可以自由選擇不同的過濾器。如果他每3秒使用一次,它只會給出內存警告(使用空的iPhone 4S而沒有運行應用程序)。如果他連續使用3,則應用程序崩潰並顯示內存警告。

Xcode顯示的內存大約爲50M,考慮到我們正在處理圖像,這是可以的。

我試過了: - 如果我在過濾器方法中分配/初始化圖像和過濾器,我會設法將其降至8M。這意味着用戶有一個很好的3秒滯後,並仍然有記憶警告。在過濾器方法結束時,我將所有內容都設置爲零,這就是瞬間顯示:它不會回落到8M,有時會回到8M,但大多數時候它會疊加到40到75/80。

  • 使用默認過濾器:它工作正常,但大約需要10到15秒來過濾圖像。當他的圖像被過濾時,我的用戶將會死亡,這是無法完成的。

  • 把一切都置於零。儘管如此,在下一個視圖中,Xcode內存顯示大約是70,而這只是常規內存。由於我設法得到了內存警告和崩潰只有8,我很確定GPU內存也是紅色的。

  • 減小尺寸並壓縮我正在使用的圖像。沒有太大的變化。它將內存使用量(由Xcode顯示)降低到45左右,但在3或4個過濾器之後仍然會出現相同的內存警告和崩潰。

注:如果我走得很慢,我真的不能,因爲我想這樣做盡可能多的過濾器和我只得到內存警告,但沒有崩潰。

我很樂意接受建議和問題,我很不滿意。這實際上只是將最基本的過濾器應用於真正經典的照片。如有必要,我可以顯示其他代碼位。

+0

remove stillImageSource = [[GPUImagePicture alloc] initWithImage:_photo]; IBAction內,你不必每次都初始化.. – 2014-10-07 14:23:30

+0

哎呀對不起。正如我在試過的問題中所說的,並且沒有每次初始化。儘管我的錯誤,但我應該首先展示最優化的代碼。我會編輯!謝謝 – 2014-10-07 14:30:18

+0

你正在使用哪個版本的Xcode ..? 。 什麼是圖像的大小和格式..? 。 您是否嘗試過更新GPUImage。is openGL 2.0 enable info plist ..'opengles-2' – 2014-10-07 14:36:52

回答

7

這是我回答你剛纔給我發電子郵件:

嗯,這裏一個大的問題是,你要和UIImages。每次你這樣做,你都會分配一個非常大的圖像,而且你沒有給我的幀緩衝優化一些機會來運行。這將導致大量的內存尖峯,特別是如果您將這些結果圖像設置爲UIImageView並繼續保留它們。

不是每次要過濾它時都創建一個新的GPUImagePicture,而是使用addTarget:創建輸入GPUImagePicture一次並鏈接過濾器。將您的UIImageView替換爲GPUImageView,然後定位您的過濾圖像。當您需要更新過濾器選項時,請更換過濾器或在過濾器上設置新選項,然後在原始源映像上調用-processImage。這將導致所有圖像處理完全駐留在GPU上(速度更快),並且會更有效地利用內存。

我還建議在您的鏈中的第一個過濾器上使用-forceProcessingAtSize:或-forceProcessingAtSizeRespectingAspectRatio:並將其設置爲視圖的目標像素大小。處理圖像的分辨率比您要顯示的分辨率更高。這也將顯着減少過濾時間和內存使用量。當您需要將最終圖像捕獲到磁盤時,可以將圖像大小重置爲0,0以消除這些限制並獲取全分辨率圖像。

+0

是的謝謝布拉德!我實際上正在閱讀它,我會讓你知道:) 感謝您的合作和幫助! – 2014-10-07 14:50:32

+0

那麼它的工作更好!我仍然必須弄清楚如何讓我的圖像「Aspect Fit」不會很小,但我可以自己想象! 謝謝布拉德,祝你有愉快的一天! – 2014-10-07 15:08:27