RexOnRoids
RexOnRoids

Reputation: 14040

Core Graphics has poor PIXEL iteration performance on iPhone?

I am trying to do an iteration on pixels to change the RGBA values of a UIImage without using OpenGL. I tried testing out iteration performance using the below code but was very displeased. It seemed like I could only get a few thousand iterations per second. And for a UIImage with several hundred thousand pixels, this would take way TOO LONG...Anybody have any suggestions on how to improve performance or how long operations like these should normally take?

-(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;    
}

Upvotes: 1

Views: 1079

Answers (3)

MoDJ
MoDJ

Reputation: 4425

The basic problem with your code is that you are treating pixels as 4 byte elements. What you need to be doing as a first step is to read a block of 4 bytes as 1 word. Use the uint32_t type and then read 1 word at a time into a register. This results in 4 times fewer memory read operations and each pixel is then stored in 1 32bit register. Each word contains RGBA with each component taking up 8 bits of the 32 bit word. You then need to use bit shift operations to manipulate the components. Here is a blog post that shows you how to do that with iOS native BGRA format pixels pixel_binary_layout. Whatever your pixel logic does, you will need to write the results out and then check those results to make sure everything is working as expected. Reading and writing whole words on a ARM chip is way way faster than doing 4x the number of byte reads, so you should see a big improvement.

Upvotes: 0

Nicholas Riley
Nicholas Riley

Reputation: 44371

Don't invoke [pixelData length] in the loop. The compiler can't know the result of this message is constant, so it'll invoke the method instead.

Upvotes: 5

Bruce Johnson
Bruce Johnson

Reputation: 155

Your NSLog statement will slow the image iteration process down considerably. A good test would be to invert the image instead of logging out the pixel data. Also calculating the data length for each iteration will also slow things down. Cache the length in a local variable and use that instead.

Upvotes: 4

Related Questions