2012-05-29 21 views
9

Soy nuevo en Quartz. Tengo 2 imágenes, un fondo y una máscara con una forma recortada que quiero extender sobre el fondo para cortar una sección. La imagen resultante debe ser la forma del corte. Esta es mi máscara (la forma en el medio es de 0 alfa):CGContextClipToMask devolver imagen en blanco

image mask

Y este es mi código:

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

Excepto no aparece nada ... ¿Alguna idea de dónde voy ¿incorrecto? Muchas gracias.

+0

Usted no lo hace parece dibujar cualquier cosa. No recortes nada de la nada y no obtienes nada. Como se esperaba. Entre recortar para enmascarar y crear la imagen, debes dibujar algo. –

Respuesta

10

Después de recortar el contexto con la máscara, debe dibujar algo en ese contexto.

Además de eso:

  • se debe utilizar para apoyar UIGraphicsBeginImageContextWithOptions factor de escala.
  • está creando dos contextos, uno con UIGraphicsBeginImageContext y el otro con CGBitmapContextCreate. Una es suficiente :)
  • debe "voltear" alfa de su máscara, porque de acuerdo con los documentos The source samples of mask determine which points of the clipping area are changed. Las otras palabras transparentes se vuelven transparentes

código de ejemplo simple, donde clip de imagen en el interior imageView y luego fijarlo de nuevo:

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; 

Ejemplo usando 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

Ya veo, ¡gracias! Solo un par de preguntas. ¿Por qué necesita llamar a TranslateCTM dos veces? Además, estoy obteniendo el efecto inverso: la parte alfa 0 de la máscara se está recortando, mientras que la parte negra de la imagen se está dibujando. De acuerdo con los documentos, necesito enmascarar la imagen con una imagen, no una máscara, usando CGImageCreateWithMask pero, ¿dónde lo uso? – Smikey

+0

UIKit y CGGraphics tienen diferentes sistemas de coordenadas, por lo que necesitamos traducir la matriz. "La parte alfa 0 de la máscara se está recortando": eso es exactamente lo que le dice la documentación para 'CGContextClipToMask' y' CGImageCreateWithMask'. Se agrega un ejemplo de 'CGImageCreateWithMask'. –

+0

Desafortunadamente ninguna de las soluciones aquí funciona ahora en ios 11 como probé, traté de enmascarar dos UIImages y usé ambos métodos. el primero aprieta la imagen después del recorte y el segundo devuelve {0.0} @Evgeny Shurakov –

Cuestiones relacionadas