views:

393

answers:

1

For example, I have a UIImage (from which I can get a CGImage, CGLayer, etc., if needed), and I want to replace all of the red pixels (1, 0, 0) with blue (0, 0, 1).

I have code to figure out which pixels are the target color (see this SO question & answer), and I can substitute the appropriate values in rawData but (a) I'm not sure how to get a UIImage back from my rawData buffer and (b) it seems like I might be missing a built-in that will do all of this for me automatically, saving me oodles of grief.

Thanks!

+1  A: 

Ok, so we got the UIImage into a rawBits buffer (see link in original question), then we twiddled the data in the buffer to our liking (i.e., set all the red-components (every 4th byte) to 0, as a test), and now need to get a new UIImage representing the twiddled data.

I found the answer in Erica Sudan's iPhone Cookbook, Chapter 7 (images), example 12 (Bitmaps). The relevant call was CGBitmapContextCreate(), and the relevant code was:

+ (UIImage *) imageWithBits: (unsigned char *) bits withSize: (CGSize)  
size
{
    // Create a color space
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    if (colorSpace == NULL)
    {
        fprintf(stderr, "Error allocating color space\n");
     free(bits);
        return nil;
    }

    CGContextRef context = CGBitmapContextCreate (bits, size.width,  
size.height, 8, size.width * 4, colorSpace,  
kCGImageAlphaPremultipliedFirst);
    if (context == NULL)
    {
        fprintf (stderr, "Error: Context not created!");
        free (bits);
     CGColorSpaceRelease(colorSpace );
     return nil;
    }

    CGColorSpaceRelease(colorSpace );
    CGImageRef ref = CGBitmapContextCreateImage(context);
    free(CGBitmapContextGetData(context));
    CGContextRelease(context);

    UIImage *img = [UIImage imageWithCGImage:ref];
    CFRelease(ref);
    return img;
}

Hope that's useful to future site spelunkers!

Olie
Shame not many people use this kind of function, you deserve more credit for this.
Luke Mcneice