2009-08-30 16 views
1

我正在嘗試對像素進行迭代,以在不使用OpenGL的情況下更改UIImage的RGBA值。我嘗試使用下面的代碼測試迭代性能,但非常不滿。似乎我每秒只能獲得幾千次迭代。而對於數十萬像素的UIImage來說,這將取代TOO LONG ...任何人對於如何提高性能或這些操作通常需要多長時間都有任何建議?Core Graphics在iPhone上的PIXEL迭代性能很差嗎?

-(UIImage*)modifyPixels:(UIImage*)originalImage 
{ 
    NSData* pixelData = (NSData*)CGDataProviderCopyData(CGImageGetDataProvider(originalImage.CGImage)); 
    void* pixelBytes = [pixelData bytes]; 

    // Take away the red pixel, assuming 32-bit RGBA 
    for(int i = 0; i < [pixelData length]; i += 4) { 
     NSLog(@" %ith iteration (%i/%i/%i/%i)", i, pixelData[i], pixelData[i+1], pixelData[i+2], pixelData[i+3]); 
    } 

    //NSData* newPixelData = [NSData dataWithBytes:pixelBytes length:[pixelData length]]; 
    //UIImage* newImage = [UIImage imageWithData:newPixelData]; 

    return originalImage;  
} 
+0

請注意,您在此處泄漏pixelData。包含「複製」的核心基礎(和通過擴展的CG)函數會返回一個保留對象。 – 2009-08-30 02:55:33

+0

好的,謝謝你。 – RexOnRoids 2009-08-30 03:17:42

回答

4

您的NSLog語句將顯着減慢圖像迭代過程。一個好的測試是反轉圖像,而不是註銷像素數據。同時計算每次迭代的數據長度也會減慢速度。緩存一個局部變量的長度並使用它。

+0

同意。 NSLog()可能會非常慢。 – 2009-08-30 02:52:17

+0

謝謝。這幫助了很多! – RexOnRoids 2009-08-30 03:02:23

5

不要在循環中調用[pixelData length]。編譯器無法知道此消息的結果是否爲常量,因此它會調用該方法。

+0

這是一個非常好的提示;我見過有經驗的開發者忽略了這一點。 – rpetrich 2009-08-30 03:44:24

0

您的代碼的基本問題是,您將像素視爲4字節元素。作爲第一步你需要做的是讀一個4字節的塊作爲1個字。使用uint32_t類型,然後每次讀取1個字到寄存器中。這會導致內存讀取操作減少4倍,然後將每個像素存儲在1 32位寄存器中。每個字包含RGBA,每個組件佔用32位字的8位。然後您需要使用位移操作來操作組件。這是一篇博客文章,向您展示如何使用iOS原生BGRA格式像素pixel_binary_layout。無論您的像素邏輯如何,您都需要將結果寫出來,然後檢查這些結果以確保一切按預期工作。在ARM芯片上讀寫整個單詞的速度要快於讀取字節數的4倍,所以你應該看到一個很大的改進。