当前位置: 首页 > news >正文

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

相关文章:

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

文章目录 1.将整个view截图返回image&#xff1a;2.截取view的部分区域&#xff0c;返回image&#xff1a;3.旧方法&#xff1a;4.Tips参考&#xff1a; 1.将整个view截图返回image&#xff1a; 这些 api 已被废弃&#xff0c;所以需要判断 iOS 版本 写两套代码&#xff1a; R…...

计算机网络——数据链路层-可靠传输的实现机制:回退N帧协议GBN(无差错情况、累积确认、有差错情况、发送窗口尺寸)

目录 回退N帧协议GBN 介绍 无差错情况 累积确认 有差错情况 发送窗口尺寸 小结 练习 解析 示意图 上篇中所介绍的停止-等待协议的信道利用率很低&#xff1b;若出现超时重传&#xff0c;则信道利用率更低。 如果发送方在收到接收方的确认分组之前可以连续发送多个数…...

IDEA debug窗口左边工具栏隐藏与显示

今天在debug排查代码的时候一不小心点到哪里&#xff0c;结果变成这样 我们可以这样恢复&#xff0c;右键Debug 点击show Toolbar...

WPF 基于TableControl的页面切换

文章目录 前言其它项目的UserControl切换TableControl添加按钮&#xff0c;隐去TableItem的Header 结论 前言 我想用WPF简单实现一个按钮视图切换的效果&#xff0c;但是我发现别人的实现效果非常的麻烦。 其它项目的UserControl切换 我网上找了个开源的项目&#xff0c;他是…...

Lua 元表,元方法

元表与元方法的概念 Lua中每个值都可具有元表。元表是普通的Lua表,定义了原始值在某些特定操作下 的行为。 例如,当table作为加法的操作数时,Lua检查其“元表”中的“__add”字段是否有 个函数。如果有,Lua调用它执行加法。我们称“元表”中的“键(如__add)”为事件(event),称…...

C# WPF上位机开发(利用tcp/ip网络访问plc)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 c# wpf如果是用来开发非标上位机的&#xff0c;那么和plc的通信肯定是少不了的。而且&#xff0c;大部分plc都支持modbus协议&#xff0c;所以这个…...

Knife4j 接口文档如何设置 Authorization 鉴权参数?

&#x1f680; 作者主页&#xff1a; 有来技术 &#x1f525; 开源项目&#xff1a; youlai-mall &#x1f343; vue3-element-admin &#x1f343; youlai-boot &#x1f33a; 仓库主页&#xff1a; Gitee &#x1f4ab; Github &#x1f4ab; GitCode &#x1f496; 欢迎点赞…...

CentOS 防火墙管理及使用的redis基本常用命令

文章目录 防火墙管理使用systemctl管理防火墙启动、关闭使用firewalld-cmd配置访问防火墙策略firewalld配置文件修改限制来源IP docker使用 redis 防火墙管理 需要关闭防火墙或者开启对应端口 使用systemctl管理防火墙启动、关闭 启动防火墙&#xff1a; systemctl start fi…...

路由器原理

目录 一.路由器 1.路由器的转发原理 2.路由器的工作原理 二.路由表 1.路由表的形成 2.路由表表头含义 直连&#xff1a; 非直连&#xff1a; 静态 静态路由的配置 负载均衡&#xff08;浮动路由&#xff09; 默认路由 动态 三.交换与路由对比 一.路由器 1.路由器…...

采埃孚4D成像雷达拆解

1 基本信息 品牌&#xff1a;海外Tier1采埃孚 • 应用&#xff1a;上汽飞凡中高端纯电平台 • 数量&#xff1a;单车2个&#xff0c;安装在前后保内部 • 最远探测距离&#xff1a;350米 拆解来看&#xff0c;4D雷达主要可以分为4个部分&#xff0c;分别为数字接口板及结构件…...

若依框架springboot——修改前端图片上传样式

简述 使用过若依框架的&#xff0c;一定知道若依前端框架上传图片的样式&#xff0c;是一个正方形加号图片&#xff0c;但是如果你要使用自定义样式呢。 比如将下面这个图进行修改呢 修改后的样式 你可以直接找到element-ui 修改上传图片的组件&#xff0c;也可以加入新的组…...

mysql 数据库 关于库的基本操作

库的操作 如果想到 mysql 客户端当中数据 系统当中的命令的话&#xff0c;直接输入的话&#xff0c;会被认为是 mysql 当中的命令。 所以&#xff0c;在mysql 当中执行系统当中的命令的话&#xff0c;要在系统命令之前带上 ststem &#xff0c;表示系统命令&#xff1a; 但是…...

【通用】Linux,VSCode,IDEA,Eclipse等资源相对位置

正文 不论是 IDEA、Linux、VSCode、cmd等等吧&#xff0c;都遵循这个规则&#xff1a; 如果以斜杠开头&#xff0c;表示从根开始找&#xff1a; IDEA的根是classpath&#xff08;classpath就是项目被编译后&#xff0c;位于 target下的 classes文件夹&#xff0c;或者位于ta…...

音视频技术开发周刊 | 323

每周一期&#xff0c;纵览音视频技术领域的干货。 新闻投稿&#xff1a;contributelivevideostack.com。 Meta牵头组建开源「AI复仇者联盟」&#xff0c;AMD等盟友800亿美元力战OpenAI英伟达 超过50家科技大厂名校和机构&#xff0c;共同成立了全新的人工智能联盟。以开源为旗号…...

STM32在CTF中的应用和快速解题

题目给的是bin文件&#xff0c;基本上就是需要我们手动修复的固件逆向。 如果给的是hex文件&#xff0c;我们可能需要使用MKD进行动态调试 主要还是以做题为目的 详细的可以去看文档&#xff1a;https://pdf1.alldatasheet.com/datasheet-pdf/view/201596/STMICROELECTRONIC…...

SaaS 电商设计 (五) 私有化部署-实现 binlog 中间件适配

一、 背景 具体的中间件私有化背景在上文 SaaS 电商设计 (二) 私有化部署-缓存中间件适配 已有做相关介绍.这里具体讨论的场景是通过解析mysql binlog 来实现mysql到其他数据源的同步.具体比如:在电商的解决方案业务流中经常有 ES 的使用场景,用以解决一些复杂的查询和搜索商品…...

Android APP 常见概念与 adb 命令

adb 的概念 adb 即 Android Debug Bridge 。在窗口输入 adb 即可显示帮助文档。adb 实际上就是在后台开启一个 server&#xff0c;会接收 adb 的命令然后帮助管理&#xff0c;控制&#xff0c;查看设备的状态、信息等&#xff0c;是开发、测试 Android 相关程序的最常用手段。…...

菜鸟学习日记(python)——函数

函数是组织好的&#xff0c;用来实现某些功能的代码块&#xff0c;它可以重复使用。 函数能提高应用的模块性&#xff0c;和代码的重复利用率。Python提供了许多内建函数&#xff0c;比如print()。但我们也可以自己创建函数&#xff0c;这被叫做用户自定义函数。 定义函数 用…...

垃圾回收 (GC) 在 .NET Core 中是如何工作的?

提起GC大家肯定不陌生&#xff0c;但是让大家是说一下GC是怎么运行的&#xff0c;可能大多数人都不太清楚&#xff0c;这也很正常&#xff0c;因为GC这东西在.NET基本不用开发者关注&#xff0c;它是依靠程序自动判断来释放托管堆的&#xff0c;我们基本不需要主动调用Collect(…...

Appium 图像识别技术 OpenCV

在我们做App自动化测试的时候&#xff0c;会发现很多场景下元素没有id、content-desc、text等等属性&#xff0c;并且有可能也会碰到由于开发采用的是自定义View&#xff0c;View中的元素也无法识别到&#xff0c;很多的自动化测试框架对此类场景束手无策。Appium在V1.9.0中有给…...

深度学习在微纳光子学中的应用

深度学习在微纳光子学中的主要应用方向 深度学习与微纳光子学的结合主要集中在以下几个方向&#xff1a; 逆向设计 通过神经网络快速预测微纳结构的光学响应&#xff0c;替代传统耗时的数值模拟方法。例如设计超表面、光子晶体等结构。 特征提取与优化 从复杂的光学数据中自…...

【根据当天日期输出明天的日期(需对闰年做判定)。】2022-5-15

缘由根据当天日期输出明天的日期(需对闰年做判定)。日期类型结构体如下&#xff1a; struct data{ int year; int month; int day;};-编程语言-CSDN问答 struct mdata{ int year; int month; int day; }mdata; int 天数(int year, int month) {switch (month){case 1: case 3:…...

Linux链表操作全解析

Linux C语言链表深度解析与实战技巧 一、链表基础概念与内核链表优势1.1 为什么使用链表&#xff1f;1.2 Linux 内核链表与用户态链表的区别 二、内核链表结构与宏解析常用宏/函数 三、内核链表的优点四、用户态链表示例五、双向循环链表在内核中的实现优势5.1 插入效率5.2 安全…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

Qt Http Server模块功能及架构

Qt Http Server 是 Qt 6.0 中引入的一个新模块&#xff0c;它提供了一个轻量级的 HTTP 服务器实现&#xff0c;主要用于构建基于 HTTP 的应用程序和服务。 功能介绍&#xff1a; 主要功能 HTTP服务器功能&#xff1a; 支持 HTTP/1.1 协议 简单的请求/响应处理模型 支持 GET…...

ServerTrust 并非唯一

NSURLAuthenticationMethodServerTrust 只是 authenticationMethod 的冰山一角 要理解 NSURLAuthenticationMethodServerTrust, 首先要明白它只是 authenticationMethod 的选项之一, 并非唯一 1 先厘清概念 点说明authenticationMethodURLAuthenticationChallenge.protectionS…...

JVM暂停(Stop-The-World,STW)的原因分类及对应排查方案

JVM暂停(Stop-The-World,STW)的完整原因分类及对应排查方案,结合JVM运行机制和常见故障场景整理而成: 一、GC相关暂停​​ 1. ​​安全点(Safepoint)阻塞​​ ​​现象​​:JVM暂停但无GC日志,日志显示No GCs detected。​​原因​​:JVM等待所有线程进入安全点(如…...

Python ROS2【机器人中间件框架】 简介

销量过万TEEIS德国护膝夏天用薄款 优惠券冠生园 百花蜂蜜428g 挤压瓶纯蜂蜜巨奇严选 鞋子除臭剂360ml 多芬身体磨砂膏280g健70%-75%酒精消毒棉片湿巾1418cm 80片/袋3袋大包清洁食品用消毒 优惠券AIMORNY52朵红玫瑰永生香皂花同城配送非鲜花七夕情人节生日礼物送女友 热卖妙洁棉…...

第2课 SiC MOSFET与 Si IGBT 静态特性对比

2.1 输出特性对比 2.2 转移特性对比 2.1 输出特性对比 器件的输出特性描述了当温度和栅源电压(栅射电压)为某一具体数值时,漏极电流(集电极电流...

本地部署drawDB结合内网穿透技术实现数据库远程管控方案

文章目录 前言1. Windows本地部署DrawDB2. 安装Cpolar内网穿透3. 实现公网访问DrawDB4. 固定DrawDB公网地址 前言 在数字化浪潮席卷全球的背景下&#xff0c;数据治理能力正日益成为构建现代企业核心竞争力的关键因素。无论是全球500强企业的数据中枢系统&#xff0c;还是初创…...