Create UIImage from shadowed view while retaining alpha?

一世执手 提交于 2019-12-18 09:35:23

问题


I have a somewhat unusual problem. In my app, I am shadowing a UIImageView using basic Quartz2d layer shadowing. Here's my code:

imageView.layer.shadowOpacity = 1.0; // Pretty self explanatory
imageView.layer.shadowRadius = 8.0; // My softness
imageView.layer.shadowColor = [UIColor blackColor].CGColor; // Color of the shadow
imageView.layer.shadowOffset = CGSizeMake(0.0, 0.0); // Offset of the shadow

This produces a nice blur behind the image view. However, I am doing some animation with this view, and the constant recalculation of the shadowing during the transitions causes a very choppy transition. What I'd like to be able to do is create a UIImage or .png file out of the image view with the blur and its alpha intact. Here's what I've already tried:

UIGraphicsBeginImageContext(CGSizeMake(320, 396)); 
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);

Since I have a shadow which "grows outside" of the image view, I can't just pass his size in the UIGraphicsBeginImageContext function. I set the correct size, but the resulting image doesn't save my alpha, instead it places a white background behind the shadow, which won't work for me because my real background is a wood texture. Also, the view isn't centered in the resulting file.

I'm pretty good with UIKit, but I'm a real noobie with Quartz 2d graphics, so if there's an obvious answer to this, send it anyway. :)


回答1:


Try setting your UIImageView's backgroundColor to [UIColor clearColor] - this may enable your current solution to work.

imageView.backgroundColor = [UIColor clearColor];
UIGraphicsBeginImageContext(CGSizeMake(320, 396)); 
[imageView.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Source: Converting a CGLayer to a *transparent* UIImage and PNG file in CoreGraphics iphone




回答2:


I've had this issue before too. My solution was not to do an image, but instead to set the shadow path to just the outline of the view you are animating.

[imageView setContentMode:UIViewContentModeScaleAspectFit];
imageView.layer.masksToBounds = NO;
imageView.layer.shadowOffset = CGSizeMake(5, 5);
imageView.layer.shadowRadius = 200;
imageView.layer.shadowOpacity = 0.5;
CGRect rect = [self rectFromImageView:imageView];
imageView.layer.shadowPath = [UIBezierPath bezierPathWithRect:rect].CGPath;

Which uses the following function which assumes the image is set to content mode aspect fit:

-(CGRect)rectFromImageView:(UIImageView *)iv {
    CGRect rect = (CGRect){{0,0},iv.frame.size};
    if (iv.image.size.width/iv.frame.size.width > iv.image.size.height/iv.frame.size.height) {
        //rect.origin.x == 0
        CGFloat sf = iv.frame.size.width/iv.image.size.width;
        rect.size.height = sf*iv.image.size.height;
        rect.origin.y = floor((iv.frame.size.height - rect.size.height)/2);
    } else {
        //rect.origin.y == 0;
        CGFloat sf = iv.frame.size.height/iv.image.size.height;
        rect.size.width = sf*iv.image.size.width;
        rect.origin.x = floor((iv.frame.size.width - rect.size.width)/2);       
    }
    return rect;
}

If your image is just set to fill then just using the imageView.bounds should be sufficient




回答3:


Add shadow path to view like this

[view.layer setShadowPath:[[UIBezierPath bezierPathWithRect:view.bounds] CGPath]]; //add path
view.layer.shadowColor = [[UIColor blackColor] CGColor];
view.layer.shadowOffset = CGSizeMake(x, y);
view.layer.shadowRadius = rad;
view.layer.shadowOpacity = 0.2f;


来源:https://stackoverflow.com/questions/7918237/create-uiimage-from-shadowed-view-while-retaining-alpha

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!