问题
我正在使用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。
答案 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
}