Sebastian Boldt
Sebastian Boldt

Reputation: 5321

How to iterate through all pixels of an UIImage?

Hey Guys i am currently trying to iterate through all pixels of an UIImage but the way i implemented it it takes sooo much time. So i thought it is the wrong way i implemented it. This is my method how i get the RGBA Values of an Pixel :

+(NSArray*)getRGBAsFromImage:(UIImage*)image atX:(int)xx andY:(int)yy count:(int)count
{
    // Initializing the result array
    NSMutableArray *result = [NSMutableArray arrayWithCapacity:count];

    // First get the image into your data buffer
    CGImageRef imageRef = [image CGImage];                      // creating an Instance of
    NSUInteger width = CGImageGetWidth(imageRef);               // Get width of our Image
    NSUInteger height = CGImageGetHeight(imageRef);             // Get height of our Image
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // creating our colour Space

    // Getting that raw Data out of an image
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));


    NSUInteger bytesPerPixel = 4;                               // Bytes per pixel defined
    NSUInteger bytesPerRow = bytesPerPixel * width;             // Bytes per row
    NSUInteger bitsPerComponent = 8;                            // Bytes per component

    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace); // releasing the color space

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

    // Now your rawData contains the image data in the RGBA8888 pixel format.
    int byteIndex = (bytesPerRow * yy) + xx * bytesPerPixel;
    for (int ii = 0 ; ii < count ; ++ii)
    {
        CGFloat red   = (rawData[byteIndex]     * 1.0) / 255.0;
        CGFloat green = (rawData[byteIndex + 1] * 1.0) / 255.0;
        CGFloat blue  = (rawData[byteIndex + 2] * 1.0) / 255.0;
        CGFloat alpha = (rawData[byteIndex + 3] * 1.0) / 255.0;
        byteIndex += 4;

        UIColor *acolor = [UIColor colorWithRed:red green:green blue:blue alpha:alpha];
        [result addObject:acolor];
    }

    free(rawData);
    return result;
}

And this is the code how i parse through all the pixels :

    for (NSUInteger y = 0 ; y < self.originalPictureWidth; y++) {
        for (NSUInteger x = 0 ; x < self.originalPictureHeight; x++) {
            NSArray * originalRGBA = [ComputerVisionHelperClass getRGBAsFromImage:self.originalPicture atX:(int)x andY:(int)y count:1];
            NSArray * referenceRGBA = [ComputerVisionHelperClass getRGBAsFromImage:self.referencePicture atX:(int)referenceIndexX andY:(int)referenceIndexY count:1];
// Do something else ....
        }
    }

Is there a faster way of getting all RGBA values of an uiimage instance ?

Upvotes: 0

Views: 987

Answers (1)

Rob Napier
Rob Napier

Reputation: 299345

For every pixel, you're generating a new copy of the image and then throwing it away. Yes, it would be much faster by just getting the data once and then processing on that byte array.

But it heavily depends on what is in "Do something else." There are many CoreImage and vImage functions that can do image processing very quickly, but you may need to approach the problem differently. It depends on what you're doing.

Upvotes: 1

Related Questions