0

I am trying to create an image mask with kCGColorSpaceDisplayP3 colorspace to support the iPhone 7's wide color range.

I am able to create image mask correctly when using sRGB colorspace on iPhone 6 and earlier devices using iOS 10 and earlier iOS. But I have no clue where I am going wrong when creating colorspace using kCGColorSpaceDisplayP3:

CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceDisplayP3);

CGContextRef context = CGBitmapContextCreate(NULL, 320.0, 320.0, 32, 320.0*16, colorSpace, kCGImageAlphaPremultipliedLast | kCGBitmapFloatComponents);

CGFloat radius = 10.0;
CGFloat components[] = {1.0,1.0,1.0,1.0,   1.0,1.0,1.0,1.0,    1.0,1.0,1.0,1.0,     1.0,1.0,1.0,1.0,    1.0,1.0,1.0,0.5,    1.0,1.0,1.0,0.0};
CGFloat locations[] = {0.0, 0.1, 0.2, 0.8, 0.9, 1.0};
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, components, locations, 6); //colorSpaceP3
CGPoint center = CGPointMake(100.0, 100.0);
CGContextDrawRadialGradient(context, gradient, center, 0.1, center, radius, 0);

CGGradientRelease(gradient);

CGImageRef imageHole = CGBitmapContextCreateImage(context);
CGImageRef maskHole = CGImageMaskCreate(CGImageGetWidth(imageHole), CGImageGetHeight(imageHole), CGImageGetBitsPerComponent(imageHole), CGImageGetBitsPerPixel(imageHole), CGImageGetBytesPerRow(imageHole), CGImageGetDataProvider(imageHole), NULL, FALSE);

CGImageRelease(imageHole);

CGImageRef image = [UIImage imageNamed:@"prosbo_hires.jpg"].CGImage;
CGImageRef masked = CGImageCreateWithMask(image, maskHole);

CGImageRelease(maskHole);
UIImage *img = [UIImage imageWithCGImage:masked];
CGImageRelease(masked);

CGContextRelease(context);
CGColorSpaceRelease(colorSpace);

The log says:

: CGImageMaskCreate: invalid mask bits/component: 32.

I don't have much experience with Core Graphics. Can anyone please suggest something here.

Thanks.

maven25
  • 231
  • 2
  • 12

2 Answers2

1

The documentation for the bitsPerComponent parameter of CGImageMaskCreate() says:

Image masks must be 1, 2, 4, or 8 bits per component.

You're passing CGImageGetBitsPerComponent(imageHole), which is 32 bits per component. As per both the documentation and the log message, that's not valid.

The implication is that image masks don't support floating point bitmap formats.

It should be possible to create the bitmap context and the mask using 8 bits per component. More or less, just leave out kCGBitmapFloatComponents. I expect that will result in reduced granularity of the opacity of the mask, but won't affect the color range of masked images.

Ken Thomases
  • 88,520
  • 7
  • 116
  • 154
  • I tried creating both bitmap context and the mask using 8 bit per complement. This works fine on all devices below iPhone 7. In iPhone 7 and 7+ the resulting image's opacity is nearly neglible. It is almost transparent. – maven25 Feb 02 '17 at 15:52
0

this fixed my issue:

contextRef = CGBitmapContextCreate(
    m.data,
    m.cols,
    m.rows,
    8,
    m.step[0], 
    CGColorSpaceCreateDeviceRGB(),
    bitmapInfo);

https://developer.apple.com/search/?q=CGColorSpaceCreate

Alej priv
  • 81
  • 6