2011-02-08 2 views
12

Я хочу создать объект UIImage с UIView. Представление НЕ непрозрачно. для этого я использую следующий код:Проблема с прозрачностью при преобразовании UIView в UIImage

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

Но по какой-то причине вместо прозрачного фона я получаю изображение с черным фоном. Я уже пытался установить «непрозрачный» параметр в UIGraphicsBeginImageContextWithOptions на NO, но без каких-либо разных результатов.

Любое предложение?

(Подобный вопрос CGContext transparency problem без ответа)

ответ

2

Я уверен, что вы не можете определить прозрачность при создании UIImages как это - вы можете замаскировать ваш UIImageView, которая использует изображение, хотя.

Что-то вроде следующих функций позволяют использовать этот тип операции:

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

Вы можете, чем назвать его так:

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

masked_image.png должен быть альфа-каналам изображения, которое будет вырежьте свой черный bg.

+0

Можете ли вы дать мне более подробно, что вы имеете в виду под «маскировка мой взгляд изображения»? И выполнит ли он то, что я пытаюсь достичь? –

+0

can gif изображение можно использовать в качестве маскирующего изображения? – Dhruv

+0

@Lemonsanver: CopyImageAndAddAlphaChannel Я получил это как неопределенный символ. Пожалуйста, скажите мне, что можно сделать сейчас. – Seeker

0

Я только что наткнулся на эту же проблему. что работало для меня, было обеспечение того, что я работал с PNG, а не с JPG, поскольку JPG не поддерживают альфа-канал. Надеюсь, что это работает для вас.

42

Если я что-то не хватает, я полагаю, вы получите результат, который вы хотите, установив непрозрачна для 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

Вы спасли мой день! –

+0

hahaha отличный ответ. не уверен, почему это не отмечено как решение, но w.e! –

+0

Вместо того, чтобы явно указывать параметр opaque в значение NO, вместо этого используйте 'view.opaque', при условии, что представление определено как непрозрачное. Это позволяет использовать тот же код для непрозрачных и непрозрачных представлений. –

Смежные вопросы