Come posso mascherare un UIImageView?

Sto cercando di mascherare un’immagine con qualcosa del genere:

immagine da mascherare

Per favore, aiutami?

Sto usando questo codice:

- (void) viewDidLoad { UIImage *OrigImage = [UIImage imageNamed:@"dogs.png"]; UIImage *mask = [UIImage imageNamed:@"mask.png"]; UIImage *maskedImage = [self maskImage:OrigImage withMask:mask]; myUIIMage.image = maskedImage; } 

C’è un modo più semplice.

 #import  // remember to include Framework as well CALayer *mask = [CALayer layer]; mask.contents = (id)[[UIImage imageNamed:@"mask.png"] CGImage]; mask.frame = CGRectMake(0, 0, , ); yourImageView.layer.mask = mask; yourImageView.layer.masksToBounds = YES; 

Per Swift 4 e più segui il codice qui sotto

 let mask = CALayer() mask.contents = [ UIImage(named: "right_challenge_bg")?.cgImage] as Any mask.frame = CGRect(x: 0, y: 0, width: leftBGImage.frame.size.width, height: leftBGImage.frame.size.height) leftBGImage.layer.mask = mask leftBGImage.layer.masksToBounds = true 

Il tutorial utilizza questo metodo con due parametri: image e maskImage , che devi impostare quando chiami il metodo. Un esempio di chiamata potrebbe assomigliare a questo, supponendo che il metodo sia nella stessa class e che le immagini siano nel tuo bundle:

Nota: incredibilmente le immagini non devono nemmeno avere la stessa dimensione.

 ... UIImage *image = [UIImage imageNamed:@"dogs.png"]; UIImage *mask = [UIImage imageNamed:@"mask.png"]; // result of the masking method UIImage *maskedImage = [self maskImage:image withMask:mask]; ... - (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage { CGImageRef maskRef = maskImage.CGImage; CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef), CGImageGetHeight(maskRef), CGImageGetBitsPerComponent(maskRef), CGImageGetBitsPerPixel(maskRef), CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), NULL, false); CGImageRef maskedImageRef = CGImageCreateWithMask([image CGImage], mask); UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef]; CGImageRelease(mask); CGImageRelease(maskedImageRef); // returns new image with mask applied return maskedImage; } 

Dopo aver fornito il codice, ho aggiunto alcuni numeri come commenti per riferimento. Hai ancora due opzioni. Tutta questa cosa è un metodo, che stai chiamando da qualche parte. Non è necessario creare le immagini al suo interno: questo riduce a zero la riusabilità del metodo.

Per far funzionare il tuo codice. Cambia i metodi head ( 1. ) in

 - (UIImage *)maskImageMyImages { 

Quindi modificare il nome della variabile in 2. a

 UIImage *maskImage = [UIImage imageNamed:@"mask.png"]; 

Il metodo restituirà le tue immagini mascherate, quindi dovrai chiamare questo metodo in qualche posto. Puoi mostrarci il codice dove stai chiamando il tuo metodo?

Ho provato entrambi i codici usando CALayer o CGImageCreateWithMask ma nessuno di loro non ha funzionato per me

Ma ho scoperto che il problema è con il formato di file png, NON il codice !!
quindi, solo per condividere la mia scoperta!

Se vuoi usarlo

 - (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage 

devi usare png a 24 bit senza canale alfa

Se si desidera utilizzare la maschera CALayer, è necessario utilizzare (24 bit o 8 bit) png con canale alfa dove la parte trasparente del png maschererà l’immagine (per la maschera alfa sfumatura uniforms .. utilizzare png a 24 bit con canale alfa)

 - (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage { CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); CGImageRef maskImageRef = [maskImage CGImage]; // create a bitmap graphics context the size of the image CGContextRef mainViewContentContext = CGBitmapContextCreate (NULL, maskImage.size.width, maskImage.size.height, 8, 0, colorSpace, kCGImageAlphaPremultipliedLast); CGColorSpaceRelease(colorSpace); if (mainViewContentContext==NULL) return NULL; CGFloat ratio = 0; ratio = maskImage.size.width/ image.size.width; if(ratio * image.size.height < maskImage.size.height) { ratio = maskImage.size.height/ image.size.height; } CGRect rect1 = {{0, 0}, {maskImage.size.width, maskImage.size.height}}; CGRect rect2 = {{-((image.size.width*ratio)-maskImage.size.width)/2 , -((image.size.height*ratio)-maskImage.size.height)/2}, {image.size.width*ratio, image.size.height*ratio}}; CGContextClipToMask(mainViewContentContext, rect1, maskImageRef); CGContextDrawImage(mainViewContentContext, rect2, image.CGImage); // Create CGImageRef of the main view bitmap content, and then // release that bitmap context CGImageRef newImage = CGBitmapContextCreateImage(mainViewContentContext); CGContextRelease(mainViewContentContext); UIImage *theImage = [UIImage imageWithCGImage:newImage]; CGImageRelease(newImage); // return the image return theImage; } 

Questo funziona per me.

Swift 3 – La soluzione più semplice che ho trovato

Ho creato un @IBDesignable per questo in modo da poter vedere immediatamente l’effetto sullo storyboard.

 import UIKit @IBDesignable class UIImageViewWithMask: UIImageView { var maskImageView = UIImageView() @IBInspectable var maskImage: UIImage? { didSet { maskImageView.image = maskImage updateView() } } // This updates mask size when changing device orientation (portrait/landscape) override func layoutSubviews() { super.layoutSubviews() updateView() } func updateView() { if maskImageView.image != nil { maskImageView.frame = bounds mask = maskImageView } } } 

Come usare

  1. Crea un nuovo file e incolla il codice sopra.
  2. Aggiungi UIImageView allo storyboard (assegna un’immagine se lo desideri).
  3. In Identity Inspector: modifica la class personalizzata in “UIImageViewWithMask” (nome class personalizzato sopra).
  4. Su Ispettore attributi: selezionare l’immagine maschera che si desidera utilizzare.

Esempio

Mascherare sullo Storyboard

Gli appunti

  • L’immagine della maschera deve avere uno sfondo trasparente (PNG) per la parte non nera.

SWIFT 3 XCODE 8.1

 func maskImage(image: UIImage, withMask maskImage: UIImage) -> UIImage { let maskRef = maskImage.cgImage let mask = CGImage( maskWidth: maskRef!.width, height: maskRef!.height, bitsPerComponent: maskRef!.bitsPerComponent, bitsPerPixel: maskRef!.bitsPerPixel, bytesPerRow: maskRef!.bytesPerRow, provider: maskRef!.dataProvider!, decode: nil, shouldInterpolate: false) let masked = image.cgImage!.masking(mask!) let maskedImage = UIImage(cgImage: masked!) // No need to release. Core Foundation objects are automatically memory managed. return maskedImage } 

// per uso

 testImage.image = maskImage(image: UIImage(named: "OriginalImage")!, withMask: UIImage(named: "maskImage")!) 

Versione rapida della soluzione accettata:

 func maskImage(image: UIImage, withMask maskImage: UIImage) -> UIImage { let maskRef = maskImage.CGImage let mask = CGImageMaskCreate( CGImageGetWidth(maskRef), CGImageGetHeight(maskRef), CGImageGetBitsPerComponent(maskRef), CGImageGetBitsPerPixel(maskRef), CGImageGetBytesPerRow(maskRef), CGImageGetDataProvider(maskRef), nil, false) let masked = CGImageCreateWithMask(image.CGImage, mask) let maskedImage = UIImage(CGImage: masked)! // No need to release. Core Foundation objects are automatically memory managed. return maskedImage } 

Nel caso qualcuno ne avesse bisogno.

Funziona per me in modo impeccabile.

abbiamo scoperto che la risposta corretta non funziona ora e ha implementato una piccola class drop-in, che aiuta a mascherare qualsiasi immagine in UIImageView.

È disponibile qui: https://github.com/Werbary/WBMaskedImageView

Esempio:

 WBMaskedImageView *imgView = [[WBMaskedImageView alloc] initWithFrame:frame]; imgView.originalImage = [UIImage imageNamed:@"original_image.png"]; imgView.maskImage = [UIImage imageNamed:@"mask_image.png"];