iOS:使用Core Graphics创建一个带孔的矩形

时间:2014-05-25 21:22:47

标签: ios core-graphics mapkit

我有一个MKMapView,我想要将地图的某些部分变灰。更具体地说,我希望有一些正常显示的圆和矩形,地图的其余部分有一个半透明的灰色层。像这样:

enter image description here

为此,我认为我应该继承MKOverlayMKOverlayRenderer。正如Apple建议的那样,在我的MKOverlayRenderer子类中,我应该覆盖drawMapRect:zoomScale:inContext:方法,并使用Core Graphics绘制我的东西。我的问题是如何使用Core Graphics绘制以下内容?

enter image description here

我花了几个小时看着使用Core Graphics进行屏蔽和剪辑,但我没有发现任何类似的东西。 QuartzDemo有一些剪切和屏蔽的例子。我想用偶数或非零绕组数规则进行裁剪对我来说不起作用,因为矩形和圆形是动态的。我想我必须以某种方式创建一个面具,但我无法弄清楚如何。 QuartzDemo creates a mask out of an image。我怎么能用矩形和圆圈创建一个蒙版?还有其他方法可以解决这个问题吗?

谢谢

2 个答案:

答案 0 :(得分:0)

您应该能够设置具有透明度的上下文,绘制粗糙的矩形和圆圈而不抚摸它们,在整个上下文周围绘制一个矩形边框,然后用较暗的颜色填充形状。您需要调查fill order rules以确保更大的空间是填充的而不是较小的连接形状。

  

我认为使用偶数或非零绕组数规则的剪辑对我来说不起作用,因为矩形和圆形是动态的。

这不重要。

答案 1 :(得分:0)

好吧,我自己做了。我必须创建自己的面具。这是通过绘制“孔”形状,将其输出到ImageRef,并反转此ImageRef以输出蒙版来完成的。如果您在QuartzClipping.m项目> QuartzClippingView - > drawInContext类中添加-(void)drawInContext:(CGContextRef)context { // ... CGContextSaveGState(context); // dimension of the square mask int dimension = 20; // create mask UIGraphicsBeginImageContextWithOptions(CGSizeMake(dimension, dimension), NO, 0.0f); CGContextRef newContext = UIGraphicsGetCurrentContext(); // draw overlapping circle holes CGContextFillEllipseInRect(newContext, CGRectMake(0, 0, 10, 10)); CGContextFillEllipseInRect(newContext, CGRectMake(0, 7, 10, 10)); // draw mask CGImageRef mask = CGBitmapContextCreateImage(UIGraphicsGetCurrentContext()); UIGraphicsEndImageContext(); // the inverted mask is what we need CGImageRef invertedMask = [self invertMask:mask dimension:dimension]; CGRect rectToDraw = CGRectMake(210.0, height - 290.0, 90.0, 90.0); // everything drawn in rectToDraw after this will have two holes CGContextClipToMask(context, rectToDraw, invertedMask); // drawing a red rectangle for this demo CGContextFillRect(context, rectToDraw); CGContextRestoreGState(context); } // taken from the QuartzMaskingView below - (CGImageRef)invertMask:(CGImageRef)originalMask dimension:(int)dimension{ // To show the difference with an image mask, we take the above image and process it to extract // the alpha channel as a mask. // Allocate data NSMutableData *data = [NSMutableData dataWithLength:dimension * dimension * 1]; // Create a bitmap context CGContextRef context = CGBitmapContextCreate([data mutableBytes], dimension, dimension, 8, dimension, NULL, (CGBitmapInfo)kCGImageAlphaOnly); // Set the blend mode to copy to avoid any alteration of the source data CGContextSetBlendMode(context, kCGBlendModeCopy); // Draw the image to extract the alpha channel CGContextDrawImage(context, CGRectMake(0.0, 0.0, dimension, dimension), originalMask); // Now the alpha channel has been copied into our NSData object above, so discard the context and lets make an image mask. CGContextRelease(context); // Create a data provider for our data object (NSMutableData is tollfree bridged to CFMutableDataRef, which is compatible with CFDataRef) CGDataProviderRef dataProvider = CGDataProviderCreateWithCFData((__bridge CFMutableDataRef)data); // Create our new mask image with the same size as the original image return CGImageMaskCreate(dimension, dimension, 8, 8, dimension, dataProvider, NULL, YES); } 方法的末尾,则可以使用以下代码段。

{{1}}

欢迎任何更简单/更有效的解决方案:)