Проблема прозрачности - при преобразовании UIView в UIImage

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

+ (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 без ответа)


person Avi Shukron    schedule 08.02.2011    source источник


Ответы (3)


Я почти уверен, что вы не можете определить прозрачность при создании таких 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 должно быть изображение с альфа-каналом, которое будет вырезать ваш черный фон.

person dijipiji    schedule 08.02.2011
comment
Не могли бы вы рассказать мне подробнее, что вы имеете в виду, когда скрываете мое изображение? И достигнет ли он того, чего я пытаюсь достичь? - person Avi Shukron; 08.02.2011
comment
Можно ли использовать изображение в формате gif в качестве маскирующего изображения? - person Dhruv; 20.06.2012
comment
@Lemonsanver: CopyImageAndAddAlphaChannel Я получил это как неопределенный символ .. Скажите, пожалуйста, что теперь можно сделать - person Seeker; 28.11.2013

Если я чего-то не упустил, я считаю, что вы получите желаемый результат, установив для непрозрачности значение 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; 
}  
person Alex Finlayson    schedule 30.09.2012
comment
хахаха отличный ответ. не уверен, почему это не помечено как решение, но w.e! - person Will Von Ullrich; 23.07.2015
comment
Вместо того, чтобы явно устанавливать для параметра непрозрачности значение NO, используйте 'view.opaque', при условии, что представление было определено как непрозрачное. Это позволяет одному и тому же коду работать для непрозрачных и непрозрачных представлений. - person Martyn Davis; 27.08.2015
comment
Это сработало! Огромное спасибо. Разве какой-нибудь модератор не может установить это как правильный ответ? - person Crashalot; 24.01.2016
comment
Чувак, ты напоминаешь всем нам, что нам нужно на самом деле читать подписи и описания функций к ним ... - person Soberman; 26.01.2016

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

person iksnae    schedule 07.09.2011