2012-05-29 16 views
9

Sono nuovo al quarzo. Ho 2 immagini, uno sfondo e una maschera con una forma ritagliata che voglio posare sullo sfondo per ritagliare una sezione. L'immagine risultante dovrebbe essere la forma del ritaglio. Questa è la mia maschera (la forma in mezzo è 0 alpha):CGContextClipToMask restituisce un'immagine vuota

image mask

E questo è il mio codice:

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

Tranne appare niente ... Hai idea di dove sto andando sbagliato? Grazie molto.

+0

Non lo sai sembra disegnare qualsiasi cosa. Non tocchi nulla dal nulla e non ottieni nulla. Come previsto. Tra il ritaglio per mascherare e creare l'immagine, dovresti disegnare qualcosa. –

risposta

10

Dopo aver ritagliato il contesto con la maschera, si dovrebbe effettivamente disegnare qualcosa in quel contesto.

Oltre a questo:

  • si dovrebbe usare UIGraphicsBeginImageContextWithOptions per sostenere fattore di scala.
  • si sta creando due contesto, uno con UIGraphicsBeginImageContext e l'altro con CGBitmapContextCreate. Uno è abbastanza :)
  • si dovrebbe "capovolgere" alfa della maschera, perché secondo i documenti The source samples of mask determine which points of the clipping area are changed. Le altre parole trasparenti diventerà trasparente

codice di esempio semplice, dove ho clip immagine all'interno ImageView e quindi impostare nuovamente:

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; 

Esempio con 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); 
+0

Vedo, grazie! Solo un paio di domande Perché devi chiamare TranslateCTM due volte? Inoltre, sto ottenendo l'effetto inverso: la parte alfa 0 della maschera viene tagliata, mentre viene disegnata la parte nera dell'immagine. Secondo i documenti, ho bisogno di mascherare l'immagine con un'immagine, non con una maschera, usando CGImageCreateWithMask ma dove lo uso? – Smikey

+0

UIKit e CGGraphics hanno sistemi di coordinate diversi, quindi è necessario tradurre la matrice. "La parte alpha 0 della maschera viene tagliata" - questo è esattamente ciò che la documentazione per 'CGContextClipToMask' e' CGImageCreateWithMask' ti dice. Viene aggiunto un esempio di 'CGImageCreateWithMask'. –

+0

Sfortunatamente nessuna delle soluzioni qui funziona ora in iOS 11 come ho provato, ho provato a mascherare due UIImages e usato entrambi questi metodi. il primo schiaccia l'immagine dopo il ritaglio e il secondo restituisce {0.0} @Evgeny Shurakov –