CGBitmapContextCreate returns NULL for some pixels of width and height

1k Views Asked by At

I have the following code to create a new bitmap graphics context.

NSLog(@"newRect Width %f",newRect.size.width);
NSLog(@"newRect Height %f",newRect.size.height);
NSLog(@"imageRef %@",imageRef);

CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                            newRect.size.width,
                                            newRect.size.height,
                                            CGImageGetBitsPerComponent(imageRef),
                                            0,
                                            CGImageGetColorSpace(imageRef),
                                            CGImageGetBitmapInfo(imageRef));

The newRect.size.width is the result of dividing the original width of UIImage by 2. The newRect.size.height is the result of dividing the original height of UIImage by 2.

But for some UIImages with sizes {3000, 2002},{3024, 4032},{4032, 3024} are okay and returning bitmap context.

But for some UIImages with sizes {1242, 2208}. Normally these are screenshots from my devices and returning NULL value.

This is the log for failed UIImage. This is the log for succeed UIImage.

Is anyone can help on my issue. Thanks.

1

There are 1 best solutions below

4
Dmytro Trofymenko On BEST ANSWER

I was not able to reproduce the problem. I would suggest to log all incoming parameters and append log to your question. Also look into console log, CGBitmapContextCreate may write something there that may give the insight about the problem.

UPDATED:

The problem you are facing has nothing to do with image size, but with combination of bitmap info/colorspace and bits per component. Here what I got in system log trying to create bitmap context with info you provided:

CGBitmapContextCreate: unsupported parameter combination:
    16 bits/component; integer;
    64 bits/pixel;
    RGB color space model; kCGImageAlphaLast;
    kCGImageByteOrder16Little byte order;
    4992 bytes/row.
Valid parameters for RGB color space model are:
    16  bits per pixel,      5  bits per component,      kCGImageAlphaNoneSkipFirst
    32  bits per pixel,      8  bits per component,      kCGImageAlphaNoneSkipFirst
    32  bits per pixel,      8  bits per component,      kCGImageAlphaNoneSkipLast
    32  bits per pixel,      8  bits per component,      kCGImageAlphaPremultipliedFirst
    32  bits per pixel,      8  bits per component,      kCGImageAlphaPremultipliedLast
    64  bits per pixel,      16 bits per component,      kCGImageAlphaPremultipliedLast
    64  bits per pixel,      16 bits per component,      kCGImageAlphaNoneSkipLast
    64  bits per pixel,      16 bits per component,      kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents
    64  bits per pixel,      16 bits per component,      kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents
    128 bits per pixel,      32 bits per component,      kCGImageAlphaPremultipliedLast|kCGBitmapFloatComponents
    128 bits per pixel,      32 bits per component,      kCGImageAlphaNoneSkipLast|kCGBitmapFloatComponents
See Quartz 2D Programming Guide (available online) for more information.

You can try to use something standard always or in case of failure, e.g.

CGContextRef bitmap = CGBitmapContextCreate(NULL,
                                            newRect.size.width,
                                            newRect.size.height,
                                            8,
                                            0,
                                            CGColorSpaceCreateDeviceRGB(),
                                            kCGImageAlphaPremultipliedFirst | kCGBitmapByteOrder32Host));

Or let system choose appropriate context for you:

   UIGraphicsBeginImageContextWithOptions(newRect.size, false, 1.0);
   CGContextRef bitmap = UIGraphicsGetCurrentContext();

   // Do your drawing here

   UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
   UIGraphicsEndImageContext();