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

文章目录

  • 1.将整个view截图返回image:
  • 2.截取view的部分区域,返回image:
  • 3.旧方法:
  • 4.Tips
  • 参考:

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.scalevar image: UIImage? = nil// 1. 创建绘图渲染格式if #available(iOS 10.0, *) {let format = UIGraphicsImageRendererFormat()format.scale = scaleformat.opaque = self.isOpaque// 2. 创建绘图渲染器let renderer = UIGraphicsImageRenderer(size: self.bounds.size,format: format)// 3. 绘制图image = renderer.image { context inlet success = self.drawHierarchy(in: self.bounds, afterScreenUpdates: true)print("draw success: \(success)")}} else {UIGraphicsBeginImageContextWithOptions(self.bounds.size, self.isOpaque, 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.sizeformat: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: imagefunc 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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/278590.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Python-类视图和蓝图

目录 一.类视图 二.蓝图 一.类视图 在Flask中&#xff0c;可通过视图函数展示视图 http://t.csdnimg.cn/r6IFG 也可基于类实现&#xff0c;类视图的好处是支持继承。标准类视图是继承flask.views模块中基类View的子类 from flask.views import View 该子类中必须重写View…

智能优化算法应用:基于和声算法3D无线传感器网络(WSN)覆盖优化 - 附代码

智能优化算法应用&#xff1a;基于和声算法3D无线传感器网络(WSN)覆盖优化 - 附代码 文章目录 智能优化算法应用&#xff1a;基于和声算法3D无线传感器网络(WSN)覆盖优化 - 附代码1.无线传感网络节点模型2.覆盖数学模型及分析3.和声算法4.实验参数设定5.算法结果6.参考文献7.MA…

BearPi Std 板从入门到放弃 - 先天神魂篇(5)(RT-Thread 按键响应)

简介 使用BearPi IOT Std开发板及主板自带两颗按键与用户灯, 实现按键控制灯亮灯灭主板: 主芯片: STM32L431RCT6 LED : PC13 \ 推挽输出\ 高电平点亮 串口: Usart1 KEY1 : PB2 \ 上拉 \ 按下下降沿触发(一次)/上下沿触发(两次&#xff0c;实现按下开、松开关) KEY2 : PB3 \ 上…

UML-认识6种箭头(画类图无烦恼)

文章目录 一、背景二、箭头详解2.1 泛化&#xff08;Generalization&#xff09;2.2 实现&#xff08;Realize&#xff09;2.3 依赖&#xff08;Dependency&#xff09;2.4 关联&#xff08;Association&#xff09;2.5 聚合&#xff08;Aggregation&#xff09;2.6 组合&#…

媒体直播平台有哪些,活动直播如何扩大曝光?

传媒如春雨&#xff0c;润物细无声&#xff0c;大家好&#xff0c;我是51媒体网胡老师。 媒体直播平台包括人民视频、新华社现场云、中国网、新浪新闻直播、搜狐视频直播、凤凰新闻直播、腾讯新闻直播等。活动直播想要扩大曝光&#xff0c;可以考虑以下方式&#xff1a; 1.选择…

【Unity】简单实现生成式电子围栏

【Unity】简单实现生成式电子围栏 三维电子围栏是一种通过使用三维技术和电子设备来建立虚拟围栏&#xff0c;用于监控和控制特定区域的系统。它可以通过使用传感器和摄像头来检测任何越界行为&#xff0c;并及时发出警报。这种技术可以应用于安防领域以及其他需要对特定区域进…

股票交易信息实时大屏(Kafka+storm+Redis+DataV)

目录 引言 需求分析&#xff1a; 思路 数据源&#xff1a; 数据传输&#xff1a; 数据处理&#xff1a; 数据统计&#xff1a; 数据可视化&#xff1a; 数据提取&#xff1a; 技术栈 技术实现 前端界面搭建 布局: ​ 组件&#xff1a; 通信&#x…

Netty常见的设计模式

简介 设计模式在软件开发中起着至关重要的作用&#xff0c;它们是解决常见问题的经过验证的解决方案。而Netty作为一个优秀的网络应用程序框架&#xff0c;同样也采用了许多设计模式来提供高性能和可扩展性。在本文中&#xff0c;我们将探讨Netty中使用的一些关键设计模式&…

修改yocto容量和编译

方法1&#xff1a; 1、修改bitbake.conf cd /home/yocto_build/axxia_support/yocto_build/poky/meta/conf/ vi bitbake.conf修改倍数参数&#xff0c;1.3为5G&#xff0c;13为50G IMAGE_OVERHEAD_FACTOR修改这个参数容量&#xff0c;大于initramfs&#xff0c;不然会报错 I…

目标检测图片截取目标分类图片

如果要训练一个分类模型却没有特定的分类数据集怎么办呢&#xff1f;可以换一种思路&#xff0c;将带有该目标的图片对所有想要的目标进行画标注框然后进行截图&#xff0c;就能得到特定的分类数据了。这么做的目的是&#xff1a;带有该目标的图片可能不会少&#xff0c;但是带…

Go 与 Rust:现代编程语言的深度对比

在快速发展的软件开发领域中&#xff0c;选择合适的编程语言对项目的成功至关重要。Go 和 Rust 是两种现代编程语言&#xff0c;它们都各自拥有一系列独特的特性和优势。本文旨在深入比较 Go 和 Rust&#xff0c;从不同的角度分析这两种语言&#xff0c;包括性能、语言特性、生…

UG NX二次开发(C++)-库缺少需要的入口点的原因与解决方案

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 1、前言2、“库缺少需要的入口点”错误展示3、可能出现的原因与解决方案3.1 对于采用CTRL+U方式调用3.2 对于menu菜单下调用1、前言 在UG NX二次开发过程中,有时会遇到形形色色的bug,比如有个读…