【问题标题】:CGContextClipToMask returning blank imageCGContextClipToMask 返回空白图像
【发布时间】:2012-06-03 19:53:15
【问题描述】:

我是 Quartz 的新手。我有 2 张图像、一个背景和一个带有切口形状的蒙版,我想将它们放在背景上以切出一个部分。生成的图像应该是切口的形状。这是我的面具(中间的形状是 0 alpha):

这是我的代码:

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];

除了什么都没有出现...知道我哪里出错了吗?非常感谢。

【问题讨论】:

  • 你好像什么都没画。你从一无所有中剔除,一无所获。正如预期的那样。在剪辑蒙版和创建图像之间,您应该画一些东西。

标签: objective-c quartz-graphics quartz-2d masking clipping


【解决方案1】:

使用蒙版剪辑上下文后,您实际上应该在该上下文上绘制一些东西。

除此之外:

  • 您应该使用UIGraphicsBeginImageContextWithOptions 来支持比例因子。
  • 您正在创建两个上下文,一个是UIGraphicsBeginImageContext,另一个是CGBitmapContextCreate。一个就够了:)
  • 你应该“翻转”你的面具的阿尔法,因为根据文档The source samples of mask determine which points of the clipping area are changed。其他词透明将变得透明

简单的示例代码,我在 imageView 中剪辑图像,然后将其设置回来:

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;

使用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);

【讨论】:

  • 我明白了,谢谢!只是几个问题。为什么需要调用 TranslateCTM 两次?另外,我得到了相反的效果——蒙版的 alpha 0 部分被剪掉,而图像的黑色部分正在被绘制。根据文档,我需要使用 CGImageCreateWithMask 用图像而不是遮罩来遮罩图像,但我在哪里使用它?
  • UIKit 和 CGGraphics 坐标系不同,所以我们需要平移矩阵。 “蒙版的 alpha 0 部分被剪掉了”——这正是 CGContextClipToMaskCGImageCreateWithMask 的文档告诉你的。添加了CGImageCreateWithMask 的示例。
  • 不幸的是,当我测试时,这里的解决方案现在都不能在 ios 11 中工作,我试图屏蔽两个 UIImage 并使用这两种方法。第一个在剪切后挤压图像,第二个返回 {0.0} @Evgeny Shurakov
猜你喜欢
  • 2015-10-28
  • 2014-03-27
  • 1970-01-01
  • 2015-02-23
  • 2022-11-12
  • 2022-01-06
  • 2015-01-03
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多