Converting RGB data into a bitmap in Objective-C++ Cocoa

ReachConnection picture ReachConnection · Oct 16, 2009 · Viewed 17.4k times · Source

I have a buffer of RGB unsigned char that I would like converted into a bitmap file, does anyone know how?

My RGB float is of the following format

R [(0,0)], G[(0,0)], B[(0,0)],R [(0,1)], G[(0,1)], B[(0,1)], R [(0,2)], G[(0,2)], B[(0,2)] .....

The values for each data unit ranges from 0 to 255. anyone has any ideas how I can go about making this conversion?

Answer

nschmidt picture nschmidt · Oct 17, 2009

You can use CGBitmapContextCreate to make a bitmap context from your raw data. Then you can create a CGImageRef from the bitmap context and save it. Unfortunately CGBitmapContextCreate is a little picky about the format of the data. It does not support 24-bit RGB data. The loop at the beginning swizzles the rgb data to rgba with an alpha value of zero at the end. You have to include and link with ApplicationServices framework.

char* rgba = (char*)malloc(width*height*4);
for(int i=0; i < width*height; ++i) {
    rgba[4*i] = myBuffer[3*i];
    rgba[4*i+1] = myBuffer[3*i+1];
    rgba[4*i+2] = myBuffer[3*i+2];
    rgba[4*i+3] = 0;
}
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bitmapContext = CGBitmapContextCreate(
    rgba,
    width,
    height,
    8, // bitsPerComponent
    4*width, // bytesPerRow
    colorSpace,
    kCGImageAlphaNoneSkipLast);

CFRelease(colorSpace);

CGImageRef cgImage = CGBitmapContextCreateImage(bitmapContext);
CFURLRef url = CFURLCreateWithFileSystemPath(kCFAllocatorDefault, CFSTR("image.png"), kCFURLPOSIXPathStyle, false);

CFStringRef type = kUTTypePNG; // or kUTTypeBMP if you like
CGImageDestinationRef dest = CGImageDestinationCreateWithURL(url, type, 1, 0);

CGImageDestinationAddImage(dest, cgImage, 0);

CFRelease(cgImage);
CFRelease(bitmapContext);
CGImageDestinationFinalize(dest);
free(rgba);