Подтвердить что ты не робот

Проблема с прозрачностью при преобразовании 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 без ответа)

4b9b3361

Ответ 1

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

Ответ 2

Если мне что-то не хватает, я считаю, что вы получите нужный результат, установив opaque в 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; 
}  

Ответ 3

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