Search code examples
objective-ccgimagecgimagesource

How to create a CGImageSourceRef from image raw data?


How to create a CGImageSourceRef from raw data? I have one file that consists only of the pixel information of an image. I know the resolution and the depth and so on (e.g. 640x860, RGB, 8bit, orientation = 1, DPI = 300). These informations aren't stored inside the file. As I already wrote, this file just stores the raw pixel information.

Now I tried the following:

NSString *path = @"/Users/.../Desktop/image";
NSData *data = [NSData dataWithContentsOfFile: path];
CFDataRef cfdata = CFDataCreate(NULL, [data bytes], [data length]);
CFDictionaryRef options;
CGImageSourceRef imageSource = CGImageSourceCreateWithData(cfdata, nil);

The image is not created correctly, because of the undefined image dimensions. I have no idea how to define the image informations (resolution and so on) for this CFImageSourceRef. Think I have to initialize the CFDictionaryRef options and deliver it to

CGImageSourceRef imageSource = CGImageSourceCreateWithData(cfdata, options);

How can I create a CFDictionaryRef that it is usable for the method CGImageSourceCreateWithData?


Solution

  • You don't want to use a CGImageSource. That's not suitable for raw pixel data. It's for standard image file formats (PNG, GIF, JPEG, etc.). You should create the CGImage directly using CGImageCreate():

    NSString *path = @"/Users/.../Desktop/image";
    NSData *data = [NSData dataWithContentsOfFile: path];
    CGDataProviderRef provider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
    CGColorSpaceRef colorspace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
    CGImageRef image = CGImageCreate(640, // width
                                     860, // height
                                     8, // bitsPerComponent
                                     32, // bitsPerPixel
                                     4 * 640, // bytesPerRow
                                     colorspace,
                                     kCGImageAlphaNoneSkipFirst, // bitmapInfo
                                     provider,
                                     NULL, // decode
                                     true, // shouldInterpolate
                                     kCGRenderingIntentDefault // intent
                                     );
    CGColorSpaceRelease(colorspace);
    CGDataProviderRelease(provider);
    

    Some of the above (bitsPerComponent, bitsPerPixel, bytesPerRow, bitmapInfo) are guesses based on your brief description of your pixel data. If they are not correct for your data, adjust them.

    You could create the data provider directly from the file using CGDataProviderCreateWithURL() or CGDataProviderCreateWithFilename(), but I decided to illustrate the more general means of creating it with raw data that could come from anywhere.