Search code examples
iosimage-processingfiltercore-graphicsquartz-2d

how to perform calculations on image raw data with CoreGraphics?


I'm trying to create specific custom filter effects on image for iOS. So far, I've been trying to get raw data using CGBitmapContextCreate. However, I don't really have an idea of how to modify my rawData. I hope to perform calculations on it. I hope to effect pixel by pixel with the rawData but I have no idea how to manipulate it.

I also don't know how I can draw my bitmap context to a UIImage, so I can render the finished product on an UIImageView.

Could somebody give me some pointers to how I might be able to achieve that?

Here's my code so far:

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

//perform calculations on rawData? or context? not sure!! i hope to effect pixel by pixel.


//am i doing this correctly?
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
//set the imageview with the new image
[imageView setImage:newImage];
CGContextRelease(context);

Solution

  • You are almost there. You can perform your transactions on the RGB and Alpha channels via:

    for (NSUInteger i = 0 ; i < rawDataSpace ; i+=4) {
            rawData[i+0] = ...              
            rawData[i+1] = ...            
            rawData[i+2] = ...             
            rawData[i+3] = ...       // = Alpha channel