透明度问题 - 将UIView转换为UIImage时

13

我想从一个不透明的 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中的"opaque"参数设置为NO,但结果没有任何改变。

有什么建议吗?

(类似问题:CGContext透明度问题,但没有答案)

3个回答

46

除非我理解有误,否则我认为通过将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; 
}  

哈哈哈,好棒的答案。不确定为什么这个没有被标记为解决方案,但无所谓! - Will Von Ullrich
不要显式地将opaque参数设置为NO,而是使用“view.opaque”,前提是视图已被定义为非opaque。这样做可以使相同的代码适用于opaque和non-opaque视图。 - Martyn Davis
这个可行!非常感谢。难道没有一位管理员可以将其设置为正确答案吗? - Crashalot
伙计,你提醒了我们所有人,我们需要实际阅读函数的签名和描述... - Soberman

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需要成为一个带有Alpha通道的图像,这将切掉您的黑色背景。


请问您能否详细说明一下“遮罩我的图像视图”是什么意思?这样做能够实现我想要的目标吗? - Avi Shukron
可以使用GIF图像作为遮罩图像吗? - Dhruv
@Lemonsanver:CopyImageAndAddAlphaChannel 我得到了未定义的符号错误。请告诉我现在该怎么办。 - Seeker

0
我刚遇到了同样的问题。对我有用的是确保我使用的是PNG而不是JPG,因为JPG不支持Alpha通道。希望这对你有用。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接