CGContextClipToMask returning blank image

佐手、 提交于 2019-12-21 04:12:08

问题


I'm new to Quartz. I have 2 images, a background, and a mask with cutout shape that I want to lay over the background in order to cut out a section. The resulting image should be the shape of the cutout. This is my mask (the shape in the middle is 0 alpha):

And this is my code:

UIView *canvas = [[[sender superview] subviews] objectAtIndex:0];

UIGraphicsBeginImageContext(canvas.bounds.size);
CGColorSpaceRef colourSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef cgContext = CGBitmapContextCreate(NULL, canvas.bounds.size.width, canvas.bounds.size.height, 8, 0, colourSpace, kCGImageAlphaPremultipliedLast);
CGColorSpaceRelease(colourSpace);

CGImageRef maskImage = [[UIImage imageNamed:@"Mask.png"] CGImage];
CGContextClipToMask(cgContext, CGRectMake(0, 0, canvas.frame.size.width, canvas.frame.size.height), maskImage);

CGImageRef maskedImageRef = CGBitmapContextCreateImage(cgContext);
CGContextRelease(cgContext);

UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];
UIGraphicsEndImageContext();

[button setBackgroundImage:maskedImage forState:UIControlStateNormal];

Except nothing appears... Any idea where I'm going wrong? Many thanks.


回答1:


After you clip context with mask you should actually draw something on that context.

Besides that:

  • you should use UIGraphicsBeginImageContextWithOptions to support scale factor.
  • you're creating two context, one with UIGraphicsBeginImageContext and the other with CGBitmapContextCreate. One is enough :)
  • you should "flip" alpha of your mask, because according to docs The source samples of mask determine which points of the clipping area are changed. The other words transparent will become transparent

Simple example code, where I clip image inside imageView and then set it back:

UIGraphicsBeginImageContextWithOptions(self.imageView.frame.size, NO, 0.0);
CGContextRef context = UIGraphicsGetCurrentContext();

CGContextTranslateCTM(context, 0.0, self.imageView.frame.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

CGImageRef maskImage = [[UIImage imageNamed:@"mask.png"] CGImage];
CGContextClipToMask(context, self.imageView.bounds, maskImage); 

CGContextTranslateCTM(context, 0.0, self.imageView.frame.size.height);
CGContextScaleCTM(context, 1.0, -1.0);

[[self.imageView image] drawInRect:self.imageView.bounds];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

self.imageView.image = image;

Example using CGImageCreateWithMask:

UIImage *image = [UIImage imageNamed:@"image"];

CGImageRef originalMask = [UIImage imageNamed:@"mask"].CGImage;
CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(originalMask),
                                    CGImageGetHeight(originalMask),
                                    CGImageGetBitsPerComponent(originalMask),
                                    CGImageGetBitsPerPixel(originalMask),
                                    CGImageGetBytesPerRow(originalMask),
                                    CGImageGetDataProvider(originalMask), nil, YES);

CGImageRef maskedImageRef = CGImageCreateWithMask(image.CGImage, mask);

UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef scale:image.scale orientation:image.imageOrientation];

CGImageRelease(mask);
CGImageRelease(maskedImageRef);


来源:https://stackoverflow.com/questions/10801723/cgcontextcliptomask-returning-blank-image

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!