Search code examples
objective-ciosuiimagearraysrgba

Edit Color Bytes in UIImage


I'm quite new to working with UIImages on the byte level, but I was hoping that someone could point me to some guides on this matter?

I am ultimately looking to edit the RGBA values of the bytes, based on certain parameters (position, color, etc.) and I know I've come across samples/tutorials for this before, but I just can't seem to find anything now.

Basically, I'm hoping to be able to break a UIImage down to its bytes and iterate over them and edit the bytes' RGBA values individually. Maybe some sample code here would be a big help as well.

I've already been working in the different image contexts and editing the images with the CG power tools, but I would like to be able to work at the byte level.

EDIT:

Sorry, but I do understand that you cannot edit the bytes in a UIImage directly. I should have asked my question more clearly. I meant to ask how can I get the bytes of a UIImage, edit those bytes and then create a new UIImage from those bytes.

As pointed out by @BradLarson, OpenGL is a better option for this and there is a great library, which was created by @BradLarson, here. Thanks @CSmith for pointing it out!


Solution

  • @MartinR has right answer, here is some code to get you started:

    UIImage *image = your image;

    CGImageRef imageRef = image.CGImage;
    NSUInteger nWidth = CGImageGetWidth(imageRef);
    NSUInteger nHeight = CGImageGetHeight(imageRef);
    NSUInteger nBytesPerRow = CGImageGetBytesPerRow(imageRef);
    NSUInteger nBitsPerPixel = CGImageGetBitsPerPixel(imageRef);
    NSUInteger nBitsPerComponent = CGImageGetBitsPerComponent(imageRef);
    NSUInteger nBytesPerPixel = nBitsPerPixel == 24 ? 3 : 4;
    
    unsigned char *rawInput = malloc (nWidth * nHeight * nBytesPerPixel);
    
    CGColorSpaceRef colorSpaceRGB = CGColorSpaceCreateDeviceRGB();
    CGContextRef context = CGBitmapContextCreate(rawInput, nWidth, nHeight, nBitsPerComponent, nBytesPerRow, colorSpaceRGB, kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);
    CGContextDrawImage (context, CGRectMake(0, 0, nWidth, nHeight), imageRef);          
    
    // modify the pixels stored in the array of 4-byte pixels at rawInput
    .
    .
    .
    
    UIImage *imageNew = [[UIImage alloc] initWithCGImage:CGBitmapContextCreateImage(context)];
    
    CGContextRelease (context);
    free (rawInput);