2009-08-30 4 views
1

Я пытаюсь выполнить итерацию по пикселям, чтобы изменить значения RGBA UIImage без использования OpenGL. Я попытался проверить производительность итерации, используя приведенный ниже код, но был очень недоволен. Казалось, что я могу получить только несколько тысяч итераций в секунду. И для UIImage с несколькими сотнями тысяч пикселей это займет много времени ... У кого-нибудь есть предложения по повышению производительности или длительности таких операций, как обычно?Core Graphics имеет плохую производительность итерации PIXEL на iPhone?

-(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. Функции Core Foundation (и CG by extension), которые включают «Копировать», возвращают вам сохраненный объект. –

+0

Хорошо, спасибо за это. – RexOnRoids

ответ

4

Ваше заявление NSLog значительно замедлит процесс итерации изображения. Хорошим тестом было бы преобразование изображения вместо того, чтобы вывести данные пикселя. Также вычисление длины данных для каждой итерации также замедлит работу. Кэшируйте длину в локальной переменной и используйте ее вместо этого.

+0

Согласен. NSLog() может быть невероятно медленным. –

+0

Спасибо. Это помогло много! – RexOnRoids

5

Не вызывайте [pixelData length] в петле. Компилятор не может знать, что результат этого сообщения является постоянным, поэтому он будет ссылаться на этот метод.

+0

Это очень хороший совет; Я видел, что даже опытные разработчики этого не замечают. – rpetrich

0

Основная проблема с вашим кодом заключается в том, что вы обрабатываете пиксели как 4 байтовых элемента. То, что вам нужно сделать в качестве первого шага, - прочитать блок из 4 байтов в виде 1 слова. Используйте тип uint32_t, а затем прочитайте по одному слову в регистр. Это приводит к 4-кратному количеству операций чтения памяти, и каждый пиксель затем сохраняется в 1 32-битном регистре. Каждое слово содержит RGBA с каждым компонентом, занимающим 8 бит 32-битного слова. Затем вам нужно использовать операции смещения бит для управления компонентами. Вот сообщение в блоге, в котором показано, как это сделать с исходными пикселями формата BGRA iOS pixel_binary_layout. Независимо от вашей логики пикселей, вам нужно будет написать результаты, а затем проверить эти результаты, чтобы убедиться, что все работает должным образом. Чтение и запись целых слов на чипе ARM происходит быстрее, чем при чтении байтов в 4 раза, поэтому вы должны увидеть значительное улучшение.

Смежные вопросы