2011-02-08 23 views
12

Quiero crear un objeto UIImage a partir de UIView. La vista NO es opaca de que estoy usando el siguiente código:Problema con la transparencia al convertir UIView a UIImage

+ (UIImage *) imageWithView:(UIView *)view 
{  
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, view.opaque, [[UIScreen mainScreen] scale]);  
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];  
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();  UIGraphicsEndImageContext();  
    return img; 
} 

Pero por alguna razón en lugar de fondo transparente que estoy recibiendo una imagen con fondo negro. Ya intenté establecer el parámetro "opaco" en UIGraphicsBeginImageContextWithOptions en NO pero sin resultados diferentes.

¿Alguna sugerencia?

(pregunta similares CGContext transparency problem sin respuesta)

Respuesta

2

Estoy bastante seguro de que no se puede definir una transparencia al crear UIImages como éste - que podría enmascarar su UIImageView que utiliza la imagen sin embargo.

Algo así como las siguientes funciones permite este tipo de operación:

// handles img masking operation 
CGImageRef CopyImageAndAddAlphaChannel(CGImageRef sourceImage) { 
    CGImageRef retVal = NULL; 

    size_t width = CGImageGetWidth(sourceImage); 
    size_t height = CGImageGetHeight(sourceImage); 

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 

    CGContextRef offscreenContext = CGBitmapContextCreate(NULL, width, height, 
                  8, 0, colorSpace, kCGImageAlphaPremultipliedFirst); 

    if (offscreenContext != NULL) { 
     CGContextDrawImage(offscreenContext, CGRectMake(0, 0, width, height), sourceImage); 

     retVal = CGBitmapContextCreateImage(offscreenContext); 
     CGContextRelease(offscreenContext); 
    } 

    CGColorSpaceRelease(colorSpace); 

    return retVal; 
} 
    // png masks can mask png, gif or jpg... 
- (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 sourceImage = [image CGImage]; 
    CGImageRef imageWithAlpha = sourceImage; 
    //add alpha channel for images that don't have one (ie GIF, JPEG, etc...) 
    //this however has a computational cost 
    if ((CGImageGetAlphaInfo(sourceImage) == kCGImageAlphaNone) || (CGImageGetAlphaInfo(sourceImage) == kCGImageAlphaNoneSkipFirst)) 
    { 
     imageWithAlpha = CopyImageAndAddAlphaChannel(sourceImage); 
    } 

    CGImageRef masked = CGImageCreateWithMask(imageWithAlpha, mask); 
    CGImageRelease(mask); 

    //release imageWithAlpha if it was created by CopyImageAndAddAlphaChannel 
    if (sourceImage != imageWithAlpha) 
    { 
     CGImageRelease(imageWithAlpha); 
    } 

    UIImage* retImage = [UIImage imageWithCGImage:masked]; 
    CGImageRelease(masked); 

    return retImage; 
} 

Usted puede llamar de esta manera:

UIImage *imgMasked = [self maskImage:[UIImage imageNamed:@"full_image.png"] withMask:[UIImage imageNamed:@"masked_image.png"]]; 

masked_image.png tiene que ser una imagen canalizado alfa que se corte su negro bg.

+0

¿Me podría dar más detalle lo que quiere usted decir con "enmascarar mi vista de la imagen"? ¿Y logrará lo que estoy tratando de lograr? –

+0

¿se puede usar la imagen gif como imagen enmascaradora? – Dhruv

+0

@Lemonsanver: CopyImageAndAddAlphaChannel Obtuve esto como un símbolo indefinido. Por favor dígame qué puede hacer ahora – Seeker

0

Acabo de encontrarme con este mismo problema. Lo que funcionó para mí fue asegurarme de que estaba trabajando con PNG y no con JPG, ya que los JPG no son compatibles con el canal alfa. Espero que esto funcione para usted.

42

A menos que me falta algo, creo que se obtiene el resultado deseado mediante el establecimiento de opaco a NO

UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale); 


+ (UIImage *) imageWithView:(UIView *)view 
{  
    UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, [[UIScreen mainScreen] scale]);  
    [view.layer renderInContext:UIGraphicsGetCurrentContext()];  
    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();  UIGraphicsEndImageContext();  
    return img; 
} 
+1

¡Me salvó el día! –

+0

jajaja gran respuesta. no estoy seguro de por qué esto no está marcado como la solución, pero w.e! –

+0

En lugar de establecer explícitamente el parámetro opaco en NO, use 'view.opaque' en su lugar, siempre que la vista se haya definido como no opaca. Esto permite que el mismo código funcione para vistas opacas y no opacas. –

Cuestiones relacionadas