How can I create a CGImageSourceRef from image source data?
How to create CGImageSourceRef
from raw data? I have one file which only consists of image pixel information. I know the resolution and depth, etc. (For example, 640x860, RGB, 8 bit, orientation = 1, DPI = 300). This data is not stored inside the file. As I already wrote, this file only 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);
Image is not rendered correctly due to undefined image dimensions. I don't know how to determine the image information (resolution, etc.) for this CFImageSourceRef
. I think I need to initialize CFDictionaryRef options
and deliver it to
CGImageSourceRef imageSource = CGImageSourceCreateWithData(cfdata, options);
How do I create CFDictionaryRef
which can be used for a method CGImageSourceCreateWithData
?
source to share
You don't want to use CGImageSource
. This is not suitable for raw pixel data. This is for standard image file formats (PNG, GIF, JPEG, etc.). You have to create 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 data pixels. If they are incorrect for your data, please adjust them.
You can create a data provider directly from a file using CGDataProviderCreateWithURL()
or CGDataProviderCreateWithFilename()
, but I decided to illustrate more general ways to create one with raw data that can be retrieved from anywhere.
source to share
I'm not sure if this code will help you, but this is how I create images downloaded from the net. I originally found this code in one of the AFNetworking classes .
- (UIImage *)imageFromResponse:(NSHTTPURLResponse *)response data:(NSData *)data scale:(CGFloat)scale {
if (!data || [data length] == 0) {
return nil;
}
CGImageRef imageRef = NULL;
CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFDataRef)data);
if ([response.MIMEType isEqualToString:@"image/png"]) {
imageRef = CGImageCreateWithPNGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault);
} else if ([response.MIMEType isEqualToString:@"image/jpeg"]) {
imageRef = CGImageCreateWithJPEGDataProvider(dataProvider, NULL, true, kCGRenderingIntentDefault);
// CGImageCreateWithJPEGDataProvider does not properly handle CMKY, so if so, fall back to AFImageWithDataAtScale
if (imageRef) {
CGColorSpaceRef imageColorSpace = CGImageGetColorSpace(imageRef);
CGColorSpaceModel imageColorSpaceModel = CGColorSpaceGetModel(imageColorSpace);
if (imageColorSpaceModel == kCGColorSpaceModelCMYK) {
CGImageRelease(imageRef);
imageRef = NULL;
}
}
}
CGDataProviderRelease(dataProvider);
UIImage *anImage = [[UIImage alloc] initWithData:data];
UIImage *image = [[UIImage alloc] initWithCGImage:[anImage CGImage] scale:scale orientation:anImage.imageOrientation];
if (!imageRef) {
if (image.images || !image) {
return image;
}
imageRef = CGImageCreateCopy([image CGImage]);
if (!imageRef) {
return nil;
}
}
size_t width = CGImageGetWidth(imageRef);
size_t height = CGImageGetHeight(imageRef);
size_t bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
if (width * height > 1024 * 1024 || bitsPerComponent > 8) {
CGImageRelease(imageRef);
return image;
}
size_t bytesPerRow = 0; // CGImageGetBytesPerRow() calculates incorrectly in iOS 5.0, so defer to CGBitmapContextCreate
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGColorSpaceModel colorSpaceModel = CGColorSpaceGetModel(colorSpace);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
if (colorSpaceModel == kCGColorSpaceModelRGB) {
uint32_t alpha = (bitmapInfo & kCGBitmapAlphaInfoMask);
if (alpha == kCGImageAlphaNone) {
bitmapInfo &= ~kCGBitmapAlphaInfoMask;
bitmapInfo |= kCGImageAlphaNoneSkipFirst;
} else if (!(alpha == kCGImageAlphaNoneSkipFirst || alpha == kCGImageAlphaNoneSkipLast)) {
bitmapInfo &= ~kCGBitmapAlphaInfoMask;
bitmapInfo |= kCGImageAlphaPremultipliedFirst;
}
}
CGContextRef context = CGBitmapContextCreate(NULL, width, height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo);
CGColorSpaceRelease(colorSpace);
if (!context) {
CGImageRelease(imageRef);
return image;
}
CGContextDrawImage(context, CGRectMake(0.0f, 0.0f, width, height), imageRef);
CGImageRef inflatedImageRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
UIImage *inflatedImage = [[UIImage alloc] initWithCGImage:inflatedImageRef scale:scale orientation:image.imageOrientation];
CGImageRelease(inflatedImageRef);
CGImageRelease(imageRef);
return inflatedImage;
}
source to share