2010-04-12 83 views
6

我有一個方法,需要解析通過一堆大PNG圖像逐像素(每個PNGs是600x600像素)。它似乎在模擬器上效果很好,但在設備(iPad)上,我在某些內部存儲器複製功能中獲得了EXC_BAD_ACCESS。看起來大小是罪魁禍首,因爲如果我在較小的圖像上嘗試它,一切似乎都奏效。下面的方法是記憶相關的肉類。CGBitmapContextCreate在iPhone/iPad上

+ (CGRect) getAlphaBoundsForUImage: (UIImage*) image 
{  
    CGImageRef imageRef = [image CGImage]; 

NSUInteger width = CGImageGetWidth(imageRef); 
NSUInteger height = CGImageGetHeight(imageRef); 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

unsigned char *rawData = malloc(height * width * 4); 
memset(rawData,0,height * width * 4); 

NSUInteger bytesPerPixel = 4; 
NSUInteger bytesPerRow = bytesPerPixel * width; 
NSUInteger bitsPerComponent = 8; 
CGContextRef context = CGBitmapContextCreate(rawData, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big); 

CGColorSpaceRelease(colorSpace); 

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 
CGContextRelease(context); 

/* non-memory related stuff */ 

free(rawData); 

當我在一堆圖像上運行它時,它運行12次然後在模擬器上運行時沒有問題。你們有什麼想法嗎?

回答

0

我正在使用CGImageCreate()在我的iPad(當然是iPhoneOS 3.2)上發生類似的崩潰。看到你的困難給了我一個提示。我通過我的bytesPerRow對準下一個最大的電源2.

size_t bytesPerRowPower2 = (size_t) round(pow(2.0, trunc(log((double) bytesPerRow)/log(2.0)) + 1.0));

讓我們知道,如果提供2排排列的電源也可以解決你的問題解決了這個問題。您需要分配* rawData與調整後的大小,並將bytesPerRowPower2傳遞給CGBitmapContextCreate()...高度似乎不需要對齊。

0

也許CGImageGetBytesPerRow(兩個聲音的功率過大)。

0

我在直接定義行大小的應用程序中使用了兩個對齊行大小的功能,因爲我以編程方式創建圖像。但我也建議toastie在嘗試我的建議之前嘗試使用CGImageGetBytesPerRow。

3

運行12次,然後崩潰聽起來像內存不足的問題。 CGContext可能在內部創建一些大的自動發佈結構。既然你是在循環中這樣做,他們不會被釋放,所以你用盡了內存並死亡。

我不確定Core Foundation如何處理臨時對象。我不認爲CF對象具有autorelease等價物,而Core Graphics上下文幾乎可以肯定地處理CF對象而不是NSObject。

爲了減少代碼中的內存流失,我建議重構它以在開始處理之前創建一次離屏CGContext,並重復使用它來處理每個圖像。然後在完成後釋放它。這在任何情況下都會更快(因爲您在循環的每次傳遞中都沒有分配大量數據結構)。

我會下注以消除您的崩潰問題,我敢打賭它也會讓您的代碼更快,更快。與其他操作相比,內存分配速度非常緩慢,而且您正在使用一些相當大的數據結構來處理600x600像素的RGBA圖像。

0

嘗試在設備上運行應用程序時運行樂器分配時,它會變成與內存相關的問題。如果您處於循環中,則在該循環內創建一個自動釋放池。

3

轉到產品 - >編輯方案 - >啓用殭屍對象。在啓用殭屍對象之前放置一個勾號。現在建立並運行它。它可以更好地爲您提供EXC_BAD_ACCES錯誤的點描述。

0

也許更換

CGColorSpaceRelease(colorSpace); 
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 

CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); 
CGColorSpaceRelease(colorSpace); 

的色彩空間裁判可能仍在某種程度上需要?只是一個隨機猜測... 甚至可能把它放在背景的釋放背後?

// cleanup 
CGContextRelease(context); 
CGColorSpaceRelease(colorSpace); 
0

我通過創建一個正方形上下文(width = height)來解決問題。每次我將數據發送到OpenGL時,我的紋理都是512x256,並且會崩潰。現在我分配一個512x512緩衝區但靜止渲染512x256。希望這可以幫助。

相關問題