iOS_给View的部分区域截图 snapshot for view

1.将整个view截图返回image:

这些 api 已被废弃,所以需要判断 iOS 版本 写两套代码:
Replace usage of UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRenderer.
Replace usage of UIGraphicsGetImageFromCurrentImageContext with UIGraphicsImageRendererContext.currentImage.

Swift 版本:

/// 截图整个view
/// - Returns: image
func mooSnapshot() -> UIImage? {
   
    if self.window == nil {
   
        return nil
    }
    let scale = UIScreen.main.scale
    var image: UIImage? = nil
    // 1. 创建绘图渲染格式
    if #available(iOS 10.0, *) {
   
        let format = UIGraphicsImageRendererFormat()
        format.scale = scale
        format.opaque = false
        // 2. 创建绘图渲染器
        let renderer = UIGraphicsImageRenderer(size: self.bounds.size,
                                               format: format)
        // 3. 绘制图
        image = renderer.image {
    context in
            let success = self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
            print("draw success: \(success)")
        }
    } else {
   
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, scale);
        let success = self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
        print("draw success: \(success)")
        image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    return image
}

OC版本:

- (UIImage * _Nullable)mooSnapshot {
   
    if (CGRectGetWidth(self.bounds) <= 0.0 || CGRectGetHeight(self.bounds) <= 0.0) {
   
        return nil;
    }
    if (!self.window) {
   
        return nil;
    }
    if (!self.superview) {
   
        return nil;
    }
    CGFloat scale = [UIScreen mainScreen].scale;
    UIImage *image = nil;
    if (@available(iOS 10.0, *)) {
   
        UIGraphicsImageRendererFormat *format = [[UIGraphicsImageRendererFormat alloc] init];
        format.scale = scale;
        format.opaque = NO;
        UIGraphicsImageRenderer *renderer = [[UIGraphicsImageRenderer alloc] initWithSize:self.bounds.size
                                                                                   format:format];
        image = [renderer imageWithActions:^(UIGraphicsImageRendererContext * _Nonnull rendererContext) {
   
            BOOL success = [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
            NSLog(@"%p, Snapshot success: %@", self, @(success));
        }];
    } else {
   
        UIGraphicsBeginImageContextWithOptions(self.bounds.size, NO, scale);
        BOOL success = [self drawViewHierarchyInRect:self.bounds afterScreenUpdates:YES];
        NSLog(@"%p,  Snapshot success: %@", self, @(success));
        image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    }
    return image;
}

2.截取view的部分区域,返回image:

Capture the frame area of the view.

Swift 版本:

import CoreGraphics
extension UIView {
   
    /// 截取view的部分区域
    /// - Parameter frame: 需要截取的区域
    /// - Returns: image
    func mooSnapshotForFrame(_ frame: CGRect) -> UIImage? {
   
        guard let image = self.mooSnapshot() else {
    return nil }
        guard let cgImage = image.cgImage else {
    return nil }
        let scale = UIScreen.main.scale
        // 根据屏幕倍率将 frame 进行缩放
        let scaledRect = CGRectApplyAffineTransform(frame, 
        											CGAffineTransformMakeScale(scale, scale))
        // 根据 缩放frame 进行裁剪
        guard let scaledCGImage = cgImage.cropping(to: scaledRect) else {
    return nil }
        let returnImage = UIImage(cgImage: scaledCGImage)
        return returnImage
    }
}

OC 版本:

- (UIImage * _Nullable)mooSnapshotForFrame:(CGRect)frame {
   
    if (CGRectGetWidth(frame) <= 0.0 || CGRectGetHeight(frame) <= 0.0) {
   
        return nil;
    }
    UIImage *image = [self mooSnapshot];
    if (!image) {
   
        return nil;
    }
    CGFloat scale = [UIScreen mainScreen].scale;
    CGRect scaledRect = CGRectApplyAffineTransform(frame, CGAffineTransformMakeScale(scale, scale));
    CGImageRef cgImage = CGImageCreateWithImageInRect(image.CGImage, scaledRect);
    UIImage *returnImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    return returnImage;
}

以下就是将一个view的上半部分截取成image后展示如下:

在这里插入图片描述


3.旧方法:

func mooSnapshot() -> UIImage? {
   
    guard CGRectGetWidth(self.bounds) > 0.0 && CGRectGetHeight(self.bounds) > 0.0 else {
   
        return nil
    }
    UIGraphicsBeginImageContextWithOptions(self.bounds.size, false, 0.0)
    let success = self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)
    print("draw success: \(success)")
    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndPDFContext()
    return image
}

Replace usage of UIGraphicsBeginImageContext with UIGraphicsImageRenderer.
Replace usage of UIGraphicsBeginImageContextWithOptions with UIGraphicsImageRenderer.
Replace usage of UIGraphicsGetImageFromCurrentImageContext with UIGraphicsImageRendererContext.currentImage.
UIGraphicsEndImageContext should only be used alongside UIGraphicsBeginImageContext[WithOptions].
这些旧的 api 已经被废弃了,用文章开头的 api 代替


4.Tips

Tips1:得在加载到父视图 layout 后触发
Tips2:width 或 height 有一个为空 drawHierarchy 就会 crash(就版iOS不会crash,新版会)


参考:

drawViewHierarchyInRect:afterScreenUpdates:
ios drawViewHierarchyInRect crash EXC_BREAKPOINT UNKNOWN

相关推荐

  1. Selenium 自动化截取网页指定区域

    2023-12-19 10:38:02       48 阅读
  2. View->View测量布局中requestLayout和forceLayout区别

    2023-12-19 10:38:02       30 阅读
  3. ffmpeg(关键帧

    2023-12-19 10:38:02       40 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2023-12-19 10:38:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2023-12-19 10:38:02       100 阅读
  3. 在Django里面运行非项目文件

    2023-12-19 10:38:02       82 阅读
  4. Python语言-面向对象

    2023-12-19 10:38:02       91 阅读

热门阅读

  1. go语言实现文件夹上传前后端代码案例

    2023-12-19 10:38:02       57 阅读
  2. 获取 jira filter issue count 方法

    2023-12-19 10:38:02       66 阅读
  3. pnpm-lock.yaml、yarn.lock以及package-lock.json的区别

    2023-12-19 10:38:02       55 阅读
  4. uniapp数据缓存(存储/获取/移出)

    2023-12-19 10:38:02       72 阅读
  5. ubuntu添加路由

    2023-12-19 10:38:02       58 阅读
  6. python爬虫---urllib

    2023-12-19 10:38:02       62 阅读