3
votes

I have this code, which I found on here, which finds the color of a pixel in an image:

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

    // First get the image into your data buffer
    CGImageRef imageRef = [image CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = malloc(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);

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

But at the line CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef); it gives an error in NSLog of <Error>: CGContextDrawImage: invalid context 0x0. It doesn't crash the app, but obviously I'd prefer not to have an error there.

Any suggests for this?

2

2 Answers

10
votes

This is usually due to the CGBitmapContextCreate failing due to an unsupported combination of flags, bitsPerComponent, etc. Try removing the kCGBitmapByteOrder32Big flag; there's an Apple doc that lists all the possible context formats - look for "Supported Pixel Formats".

4
votes

Duh, I figured it out. So silly.

When I first enter the view, the UIImageView is blank, so the method is called against an empty UIIMageView. Makes sense that it would crash with "invalid context". Of course! The UIIMageView is empty. How can it get the width and height of an image that isn't there?

If I comment out the method, pick an image, and then put the method back in, it works. Makes sense.

I just put in an if/else statement to only call the method if the image view isn't empty.