2010-06-17 27 views
26

Tôi đang làm việc trên một ứng dụng mà tôi vẽ UIView qua mã và tôi điền vào bằng UIColor. Tiếp theo, tôi muốn tải một tệp mask.png (không có độ trong suốt, chỉ đen và trắng) và mặt nạ UIView để thay đổi giao diện trực quan của nó.Cách che mặt UIView

Bất kỳ ý tưởng nào về cách thực hiện việc này?

Trả lời

5

Bạn có thể có thể sử dụng 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); 
} 
3

Cảm ơn drawnonward,

đã kết thúc với chức năng này:

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

} 
51
// 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; 

Ghi nhập khẩu QuartzCore và thêm khuôn khổ

#import <QuartzCore/QuartzCore.h> 

Rất dễ dàng nhưng tôi không tìm thấy câu trả lời ở bất cứ đâu!

+1

Bất kỳ câu trả lời nào sử dụng Hoạt ảnh lõi thay vì Đồ họa cốt lõi nên được ưu tiên. API của CA dễ hiểu và dễ sử dụng hơn nhiều. – zakdances

4

tôi đã tạo ra một loại với đoạn code trên:

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 
+0

Loại hình ảnh nào bạn có trong đầu vào? đen trắng hoặc mờ và trắng hoặc mờ và đen? – Vassily

+0

Tôi đã sử dụng hình ảnh màu đen có alpha. Nhưng tôi không nghĩ điều này sẽ tạo nên sự khác biệt. Nếu bạn thử nó, hãy cho tôi biết :). – mt81

+0

Tôi đã thử. Trên thực tế có một sự khác biệt. Chỉ thành phần alpha sẽ có hiệu lực – Arsynth

11

iOS 8 giới thiệu maskView bất động sản cho phép bạn sử dụng chế độ xem thay thế để cung cấp hình ảnh mặt nạ. Trong Swift:

if let maskImage = UIImage(named: "MaskImage") { 
    myView.maskView = UIImageView(image: maskImage) 
} 

Lưu ý rằng bạn cần cung cấp hình ảnh thực sự có độ trong suốt; một hình ảnh với các bộ phận màu trắng (cho đục) và các bộ phận màu đen (cho trong suốt) sẽ không hoạt động.

+0

Bất kỳ ý tưởng nào tại sao điều này có thể gặp sự cố với EXC_BAD_ACCESS? (- [UIImageView _maskView]: tin nhắn được gửi đến phiên bản được phân phối) – Yaroslav

0

Swift 2.0

Vượt qua một UIImage và một hình ảnh mặt nạ để chức năng này, và bạn sẽ nhận được một hình ảnh đeo mặt nạ như một 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 
}