UIGraphicsBeginImageContextWithOptions不捕获阴影/渐变

时间:2013-09-22 06:14:41

标签: ios objective-c core-animation quartz-core

问题

我正在使用UIGraphicsBeginImageContextWithOptions将屏幕截图保存到UIImage中。虽然这有效,但最终的UIImage缺少任何阴影和渐变。

如何让它也截图图层内容?


显示问题的测试代码


#import "ViewController.h"
#import <QuartzCore/QuartzCore.h>

@implementation ViewController

- (void)viewDidLoad {
    //super
    [super viewDidLoad];

    //background
    self.view.backgroundColor = [UIColor whiteColor];

    //container
    UIView *container = [[UIView alloc] initWithFrame:CGRectMake(10, 10, 300, 200)];
    container.backgroundColor = [UIColor blackColor];
    [self.view addSubview:container];

    //circle
    UIView *circle = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 10, 10)];
    circle.backgroundColor = [UIColor whiteColor];
    circle.layer.cornerRadius = 5;
    circle.layer.shadowColor = [UIColor redColor].CGColor;
    circle.layer.shadowOffset = CGSizeZero;
    circle.layer.shadowOpacity = 1;
    circle.layer.shadowRadius = 10;
    circle.layer.shadowPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(-10, -10, 30, 30)].CGPath;
    [container addSubview:circle];

    //screenshot
    UIGraphicsBeginImageContextWithOptions(container.bounds.size, container.opaque, 0.0);
    [container.layer renderInContext:UIGraphicsGetCurrentContext()];
    UIImage *screenshot = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    //image view
    UIImageView *iv = [[UIImageView alloc] initWithFrame:CGRectMake(10, 568-200-20-10, 300, 200)];
    iv.image = screenshot;
    [self.view addSubview:iv];
}

@end

SIMULATOR SCREENSHOT显示问题


顶部区域是原始视图。底部区域是带有屏幕截图的UIImageView。

Simulator Screenshot

2 个答案:

答案 0 :(得分:0)

在这一行中,

UIGraphicsBeginImageContextWithOptions(container.bounds.size,container.opaque,0.0);

put NO instead of container.opaque

使用此方法,

- (UIImage *)imageOfView:(UIView *)view
{

    if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
        UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 0.0);
    } else {
        UIGraphicsBeginImageContext(view.bounds.size);
    }

    [view.layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return img;
}

答案 1 :(得分:0)

对于图像上的阴影:

public func generateShadow(for image: UIImage, shadowOffset: CGSize,blur: CGFloat, shadowColor: CGColor ) -> UIImage? {
let size = CGSize(width: image.size.width + blur, height:
                    image.size.height +  blur)

return MediaPickerFramework.generateImage(CGSize(width: size.width, height: size.width), contextGenerator: { size, context in
    context.clear(CGRect(origin: CGPoint(), size: size))
            context.setShadow(offset: shadowOffset,
                              blur: blur,
                              color: shadowColor)
            let center = CGPoint(x: size.width / 2, y: size.height / 2)
            let imageOrigin = CGPoint(x: center.x - (image.size.width / 2), y: center.y - (image.size.height / 2))
    
            context.draw(image.cgImage!,
                         in: CGRect(x: imageOrigin.x, y: imageOrigin.y, width: image.size.width, height: image.size.height),
                         byTiling:false)
})

}

为了在图像上绘制渐变,您可以使用以下函数

 func generateGradientTintedImage(image: UIImage?, colors: [UIColor]) -> UIImage? {
guard let image = image else {
    return nil
}

let imageSize = image.size

UIGraphicsBeginImageContextWithOptions(imageSize, false, image.scale)
if let context = UIGraphicsGetCurrentContext() {
    let imageRect = CGRect(origin: CGPoint(), size: imageSize)
    context.saveGState()
    context.translateBy(x: imageRect.midX, y: imageRect.midY)
    context.scaleBy(x: 1.0, y: -1.0)
    context.translateBy(x: -imageRect.midX, y: -imageRect.midY)
    context.clip(to: imageRect, mask: image.cgImage!)
    
    let gradientColors = colors.map { $0.cgColor } as CFArray
    let delta: CGFloat = 1.0 / (CGFloat(colors.count) - 1.0)
    
    var locations: [CGFloat] = []
    for i in 0 ..< colors.count {
        locations.append(delta * CGFloat(i))
    }
    let colorSpace = CGColorSpaceCreateDeviceRGB()
    let gradient = CGGradient(colorsSpace: colorSpace, colors: gradientColors, locations: &locations)!
    
    context.drawLinearGradient(gradient, start: CGPoint(x: 0.0, y: imageRect.height), end: CGPoint(x: 0.0, y: 0.0), options: CGGradientDrawingOptions())
    
    context.restoreGState()
}

let tintedImage = UIGraphicsGetImageFromCurrentImageContext()!
UIGraphicsEndImageContext()

return tintedImage

}