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

发布于 2024-10-16 07:11:16 字数 720 浏览 1 评论 0原文

我想从 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透明度问题没有答案)

I want to create an UIImage object from a UIView. The view is NOT opaque.
for that i'm using the following code:

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

But for some reason instead of transparent background i'm getting a image with black background.
I already tried to set the "opaque" parameter in UIGraphicsBeginImageContextWithOptions to NO but with no different results.

Any suggestion?

(Similar question CGContext transparency problem with no answer)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

愿与i 2024-10-23 07:11:17

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

i just came across this same problem. what worked for me was assuring that i was working with PNGs and not JPGs, since JPGs do not support alpha channel. hope this works for you.

初心未许 2024-10-23 07:11:16

除非我遗漏了什么,否则我相信通过将 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; 
}  

Unless I'm missing something, I believe you get the result you want by setting opaque to 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; 
}  
冰葑 2024-10-23 07:11:16

我很确定在创建这样的 UIImage 时您无法定义透明度 - 您可以掩盖使用图像的 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 通道图像,它将剪掉您的黑色背景。

I'm pretty sure you can't define a transparency when creating UIImages like this - you could mask your UIImageView which uses the image though.

Something like the following functions allow for this type of operation:

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

You can than call it like this:

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

masked_image.png needs to be an alpha channeled image which will cut out your black bg.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文