如何对UIView进行遮罩处理

27

我正在开发一个应用程序,通过代码绘制UIView并使用UIColor进行填充。接下来,我想要加载一个mask.png文件(没有透明度,只有黑白)并对UIView进行遮罩以改变其外观。

有什么想法吗?

6个回答

52
// Create your mask layer
CALayer* maskLayer = [CALayer layer];
maskLayer.frame = CGRectMake(0,0,yourMaskWidth ,yourMaskHeight);
maskLayer.contents = (__bridge id)[[UIImage imageNamed:@"yourMaskImage.png"] CGImage];

// Apply the mask to your uiview layer        
yourUIView.layer.mask = maskLayer;

记得导入QuartzCore并添加框架

#import <QuartzCore/QuartzCore.h>

很容易但我在任何地方都找不到答案!


1
任何使用核心动画而不是核心图形的答案都应该被优先考虑。CA的API更易于理解和使用。 - zakdances

12

iOS 8 引入了 maskView 属性,它允许您使用另一个视图来提供蒙版图像。在 Swift 中:

iOS 8 引入的 maskView 属性可以使用替代视图来提供蒙版图像。在 Swift 中:

if let maskImage = UIImage(named: "MaskImage") {
    myView.maskView = UIImageView(image: maskImage)
}
请注意,您需要提供实际具有透明度的图像;带有白色部分(用于不透明)和黑色部分(用于透明)的图像将无法使用。

你有什么想法为什么会出现EXC_BAD_ACCESS崩溃?(-[UIImageView _maskView]:消息发送到已释放的实例) - Yaroslav

5
你可以尝试使用CGContextClipToMask:
-(void) drawRect:(CGRect)dirty {
  CGContextRef context = UIGraphicsGetCurrentContext();
  CGContextSaveGState( context );
  CGContextClipToMask( context , [self bounds] , [self maskImage] );
  [super drawRect:dirty]; // or draw your color manually
  CGContextRestoreGState( context );
}

5
我已经用上面的代码创建了一个类别:
UIView+ImageMask.h:
#import <UIKit/UIKit.h>

@interface UIView (ImageMask)

- (void) maskWithImage:(UIImage*) mask;
- (void) maskWithImage:(UIImage*)mask size:(CGSize)maskSize;
- (void) removeMask;

@end

UIView+ImageMask.m :
#import <QuartzCore/QuartzCore.h>

#import "UIView+ImageMask.h"

@implementation UIView (ImageMask)

- (void) maskWithImage:(UIImage*) mask {
    [self maskWithImage:mask size:mask.size];
}

- (void) maskWithImage:(UIImage*)mask size:(CGSize)maskSize {
    CALayer* maskLayer = [CALayer layer];
    maskLayer.frame = CGRectMake(0, 0, maskSize.size.width, maskSize.size.height);
    maskLayer.contents = (__bridge id)[mask CGImage];

    // Apply the mask to your uiview layer
    self.layer.mask = maskLayer;
}

- (void) removeMask {
    self.layer.mask = nil;
}

@end

你的输入图像是什么类型?黑白、半透明白色还是半透明黑色? - Vassily
我使用了一个带有透明度的黑色图片。但是我不认为这会有什么影响。如果你尝试过,请告诉我 :)。 - mt81
我试过了。实际上有一个差别。只有 alpha 组件会产生影响。 - Arsynth
是的,图像需要带有alpha通道的PNG格式。只有alpha通道将被掩蔽,其余部分可以是白色或黑色,这并不重要。 - Vassily

3
感谢drawnonward, 最终得到了以下函数:
- (UIImage*) maskImage:(UIView *)image withMask:(UIImage *)maskImage {

    UIGraphicsBeginImageContext(image.bounds.size);
    [image.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();


    CGImageRef maskRef = maskImage.CGImage; 

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef masked = CGImageCreateWithMask([viewImage CGImage], mask);
    return [UIImage imageWithCGImage:masked];

}

0

Swift 2.0

将UIImage和掩码图像传递给此函数,您将获得一个遮罩图像作为UIImage。

func maskImage(image:UIImage, mask:(UIImage))->UIImage{

    let imageReference = image.CGImage
    let maskReference = mask.CGImage

    let imageMask = CGImageMaskCreate(CGImageGetWidth(maskReference),
                                  CGImageGetHeight(maskReference),
                                  CGImageGetBitsPerComponent(maskReference),
                                  CGImageGetBitsPerPixel(maskReference),
                                  CGImageGetBytesPerRow(maskReference),
                                  CGImageGetDataProvider(maskReference), nil, true)

   let maskedReference = CGImageCreateWithMask(imageReference, imageMask)

   let maskedImage = UIImage(CGImage:maskedReference!)

   return maskedImage
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接