没有前面进度的同学还是从(二)开始,否则会感觉比较突兀

ios图像和图形最佳实践(二)

对于我们的app所附带的图片 苹果强烈建议我们使用图像素材来存储

这其中有很多原因

图像素材针对基于名称和基于特征的查找进行了优化

在素材目录中查找图片资源 会比搜索具有特定命名格式的磁盘上的文件要快得多(预置图像素材)

素材目录运行时在管理缓存大小方面也非常智能

还有一些与运行时性能无关的特性 是图像资源独有的 包括针对不同设备瘦身的功能 这意味着你的app只下载与其所运行的设备相关的图像资源 还有 Vector artwork 矢量图形功能

Vector artwork 是iOS11中引入的一项功能

你可以在素材编辑器中 选中“保留矢量数据 Preserve Vector Data” 复选框来启用它

其效果是如果你的图像在图像视图的渲染中 大于或小于图像的原始大小 它也不会变得模糊 这

种图像实际上是从矢量图形重新栅格化的 因此它具有很好的边缘清晰度

苹果在操作系统中的一个地方使用了这种技术

若你在 Accessibility设置中调整动态类型到一个非常大的尺寸 然后点击并按住标签栏中的项目 将会出现一个小HUD 显示当前你的手指所按住物体的放大视图

因此 如果你希望你的图片在这样的情境下看起来效果更好

那就选中图像素材管理器中的 “Preserve Vector Data” 复选框

它的工作方式 与前面提到的 管道非常类似

只是这里不是一个解码阶段,而是一个栅格化阶段 其负责获取矢量数据,并将其转化为可复制到帧缓存的位图数据

矢量图形管道

如果我们必须为app中所有矢量图形进行这项操作 我们会消耗更多的CPU资源 因此苹果在这里做了一个优化

如果你有一张选中了 “保留矢量数据”的图像 但你以正常的尺寸渲染它

实际上资源目录编译器已经生成了那个图片的预栅格化版本 并将其存储在资源目录中 因此并不需要做复杂的数学运算 来将矢量图形栅格化为位图

我们可以直接解码存储在资源目录中的图像 并将其直接渲染到帧缓存中

如果你计划以几种固定大小呈现图像

比如你有一个小图标和一个大图标 你不需要依赖 “Preserve Vector Data”复选框

只需创建你知道的两种尺寸两个图像资源 这将允许在编译期 而不是每次将图像复制到帧缓存时调用CPU对你的图片进行栅格化 从而达到优化的效果

不是每次将图像复制到帧缓存都进行计算

至此,我们已经看到了如何使用 UIImage 和 UIImageView 但你的app做的图形工作不止这些 有时app在运行时绘制内容


出于若干原因 苹果并不推荐这种方法

我们将这个视图子类与UIImageView进行比较

你可能已经知道每个UIView实际上都是依赖 CoreAnimation运行时的CALayer实现的


对于我们的图像视图 图像视图要求图像创建解码图像缓存


然后将解码后的图像交给CALayer 用作其所在层的内容

对于我们重写draw得到的自定义视图 他们很相似 但略有不同 各个层负责创建图像缓存 以便保存我们的draw方法内容 然后我们的视图执行draw函数 并填充该图像缓存的内容

接着这些内容根据显示硬件的需要 被复制到帧缓存中

为了了解这将产生多大的开销 以及为什么我们不应该寻求实现这个UI的替代方法 我们在此使用的后备存储器 即连接到CALayer的图像缓存 其大小与我们正在显示的视图大小成正比

我们在iOS12中引入了一项新功能和优化

即后备存储器中元素的大小 实际上会动态增长 取决于你是否绘制任何有颜色的内容

该色彩内容 是在标准色彩范围之内或之外

因此如果你使用扩展的SRGB颜色 绘制广色域内容 则后备存储器实际上会比仅使用0到1范围内的颜色的后备存储器大

之前的iOS版本中,你可以通过设置CALayer的内容格式属性 来作为对 Core Animation的一个提示

即我知道我不需要在这个视图中支持广色域内容 或我知道我需要在这个视图中支持广色域内容

如果你这样做 你实际上将会禁用苹果在iOS12中引入的优化

因此 请检查layerWillDraw的实现 确保你不会以外关闭这项优化 该优化能使你的运行在iOS12上的代码收益无穷

但我们可以做到比仅仅提示我们是否需要一个支持广色域的后备存储器更好 我们实际上可以减少app所需的后备存储器总量

我们可以通过将这个较大的视图重构为较小的子视图来实现这一点 同时减少或消除重写draw函数的地方

这将帮助我们消除内存中图像数据的重复副本

并且这将允许我们利用UIView的优化属性 其不需实现后备存储器

因此正如前面提到的重写draw方法 将需要创建一个后备存储器 与CALayer一起使用

但是即使你不重写draw方法 UIView中的一些属性仍然可以工作

例如设置UIView的背景颜色 并不需要重建后备存储器 除非你使用的是图案颜色

因此苹果建议 不要在UIView中使用具有背景颜色属性的图案颜色 而应该创建一个UIImageView

将你的图像分配到该图像视图并使用 UIImageView中的函数 恰当的设置平铺参数

当我们想要剪切圆角矩形的角时 我们希望使用CALayer的cornerRadius属性

因为Core Animation能够渲染削角 而不需要额外的内存分配

如果我们改用更强大的maskView 或maskLayer属性 我们最终需要额外分配内存来存储该mask

如果你拥有更复杂透明区域的背景 并且不能通过cornerRadius属性进行设置 那么你应该考虑使用UIImageView 将这些信息存储在你的素材目录中 或在运行时渲染它 并将其作为图像提供给图像视图

而不应该使用 maskView或maskLayer

最后对于该Live Photo图标 UIImageView能够对单色图稿进行着色 而不需要额外的内存分配

你要做的第一件事是勾选 不是勾选复选框 而是在图片资源编辑器中将渲染模式属性设置为always template

或在UIImageView上调用withRenderingMode函数 来创建一个渲染模式为always template的UIImage

然后将该图像分配给图像视图 并将该图像视图的tintColor设置为你想要图像渲染的颜色

在UIImage将图像渲染到帧缓存过程中 它会在该复制操作中使用纯色 而不是坚持使用应用于纯色图像的单独副本

UIKit提供的视图中内置了另一项优化

UILabel可以在显示单色文本时比显示彩色文本或表情符号时 减少75%的内存使用

如果你想更详细了解此优化的工作原理 以及如何将其应用于UIView的自定义子类

可以参考“ios内存深潜”演讲 其详细介绍了这种名为A8的后备存储器格式

有时候 你想渲染存储在内存中图像缓存中的图像

UIKit为此提供的类是UIGraphicsImageRenderer

还有另一个更旧的函数UIGraphicsBeginImageContext 但请不要使用它 因为只有UIGraphicsImageRenderer 能够正确渲染广色域内容(屏外绘制)

你可以在app中使用 UIGraphicsImageRenderer 来渲染屏幕外的地方 然后使用UIImageView在屏幕上进行高效显示

与我们在CALayer后备存储器中引入的优化类似 我们也使 UIGraphicsImageRenderer 能够动态增长其图像缓存的大小 这取决于你在操作块中执行的操作

如果你在iOS12之前的操作系统上运行代码 你可以使用 UIGraphicsImageRenderFormat 中的 prefersExtendedRange 属性来告诉UIKit 你是否计划绘制广色域内容

但这里有一个中间地带

如果你主要将图像渲染到图形图像渲染器中 该图像可能使用超出SRGB色域的色彩空间值

但实际上并不需要更大的元素尺寸来存储这些信息

UIImage有一个可以用来获取一个预构建的 UIGraphicsImageRenderFormat 对象的 image renderer format属性

该对象用于在重新渲染图像时进行最优化存储

最后将谈一些 如何在你的app中集成

如果你需要使用Core Image 对你的图片实时进行大量的高级处理(高级图像处理) 那么请考虑使用 Core Image

Core Image是这样一个框架 它允许你创建处理图像的配方 并在CPU或GPU上进行处理

如果你从CIImage创建一个UIImage并将其交给UIImageView UIImageView将负责在GPU上执行该配方

这非常高效 并且它可以保持CPU空闲从而能够在你的app中执行其他工作

为了使用它像平常一样创建你的CIImage 然后调用UIImage CIImage初始化程序

iOS上还有其他用于处理和渲染图形内容的高级框架 包括 Metal Vision 和 Accelerate

这些框架中常见的数据类型之一 是 CVPixelBuffer

这是一种数据类型 用来表示在CPU或GPU上正在使用或尚未使用的缓存

在构建这些像素缓存的其中一个时 确保使用最好的初始化程序 即最接近你手头表述的那个

不要展开任何解码工作 这些工作已经由现有的UIImage 或 CGImage实现完成了

在CPU和GPU之间移动数据时要格外小心 这样你就不会在两者之间进行权衡工作 实际上你可以让它们并行执行

最后请关注一下Accelerate框架 “如何正确格式化待处理缓存”的 Accelerate和simd演讲

三篇文章总结一下关键点

  • 在表视图和集合视图中实现预取 以便可以事先完成一些工作并避免粘连

  • 确保你没有关闭UIKit提供的任何优化 这些优化可以减少与视图关联的后备存储器大小

  • 如果你将图像与app捆绑在一起 将其存储在资源目录中 不要将其存储在与你的app相关联的文件中

  • 如果你以不同大小渲染相同的图标 不要过分依赖“Preserve Vector Data”(保留矢量数据)
    复选框

ios图像和图形最佳实践(三)相关推荐

  1. RDS最佳实践(三)—如何制定相关的流程来规范RDS的使用

    上一篇文章中,我们介绍了如何快速的把本地自建的数据库迁移入云,那是不是把数据库迁移到RDS后,用户就什么都不需要做了?比如RDS帮你的数据库做到了高可用,在主库出现down机后能够快速切换到备库,立刻 ...

  2. ASP.NETSpring.NETNHibernate最佳实践(三)——第2章环境准备

    2.1. 开发工具  Microsoft Visual Studio 2005  ASP.NET AJAX Extensions V1.0(http://www.asp.net/ajax/)  ...

  3. ios传感器应用开发最佳实践_同构 javascript 应用开发的最佳实践(Four)

    今天要做的是首先要整理代码,在现有的代码基础上抽理出一个 Applicatin 类可以作为客户端和服务端共同使用,通过不同的上下文完成不同的工作. 创建 Applicatin 类 export def ...

  4. IOS老版本应用最佳实践

    平台:iPhone13pro,IOS15.7 微信8.0.29 QQ8.8.5 TIM3.4.0 知乎6.0.0 百度贴吧12.0.5 抖音20.5.0 哔哩哔哩6.42.0 keep7.21.0 Q ...

  5. 得物技术埋点自动化验证的探索和最佳实践

    背景 埋点对电商类app的业务发展一直有着重要的指导作用,但是其复杂的数据组成使得它的稳定性难以得到保障,往往业务逻辑的一些重构就会导致一些埋点属性甚至是整个埋点的丢失. 也正是由于埋点具有多个数据源 ...

  6. MySQL性能优化、故障排查及最佳实践秘籍,阿里云数据库专家玄惭的“武功”全记录...

    为什么80%的码农都做不了架构师?>>>    文章简介 玄惭,真名罗龙九,阿里云DBA专家,负责阿里云RDS线上稳定以及专家服务团队.他经历过阿里历年双11实战考验,积累了7年对阿 ...

  7. 玄惭 mysql_阿里云数据库专家玄惭的“武功”全记录之最佳实践、双十一特别篇...

    原标题:阿里云数据库专家玄惭的"武功"全记录之最佳实践.双十一特别篇 专题简介 玄惭,真名罗龙九,阿里云DBA专家,负责阿里云RDS线上稳定以及专家服务团队.他经历过阿里历年双11 ...

  8. iOS图像最佳实践总结

    1. 前言 2018 WWDC 苹果官方给出了关于iOS图像处理的最佳实践,本文主要是就官方文档进行分析总结以及较为全面的拓展延伸. 官方文档:Image and Graphics Best Prac ...

  9. 重磅综述:三万字长文读懂单细胞RNA测序分析的最佳实践教程 (原理、代码和评述)

    原文链接: https://www.embopress.org/doi/10.15252/msb.20188746 主编评语 这篇文章最好的地方不只在于推荐了工具,提供了一套分析流程,更在于详细介绍了 ...

最新文章

  1. 【数据安全案例】北京破获贩卖个人信息案 涉及上千万条公民信息
  2. 实验管理系统java,大学生创新实验室信息管理系统 java+mysql
  3. 【Android 高性能音频】AAudio 音频流 数据回调细节 ( 数据回调函数优先级 | 数据回调函数 | 采样率 | 采样数 | 缓冲区调整 | 线程不安全 )
  4. Node.js 安装及配置
  5. oracle 群集 无存储,存储的群集注意事项 - Oracle® ZFS Storage Appliance 管理指南
  6. jmeter ---实战(详解)
  7. 不同曲线设置标签_带动态标签的面积曲线图
  8. DOSBox安装及使用教程
  9. 一文读懂模拟电路和数字电路之间的区别和联系
  10. 安卓 Handler 机制学习
  11. 数字孪生堆场智慧安全管控平台
  12. AVI编码器的常见编码
  13. 特殊命令之REG命令
  14. 计算机编辑功能在哪,win10系统本地组策略编辑器在哪的具体步骤
  15. WPF 开机一键启动程序V1.0【原创】
  16. 【ArchSummit】社交元宇宙的技术挑战与探索
  17. 【Java学习笔记】2023_03_10Java基础
  18. win10系统访问局域网服务器,Win10系统不能访问局域网共享磁盘的解决方法
  19. linux常用端口查询
  20. 氢氧化锂制备系统——吸附(除杂\提锂)+双极膜电渗析

热门文章

  1. 全球零碳产业园标准率先发布;黑芝麻智能与江汽集团战略合作 | 美通企业日报...
  2. Python 头像上右下角添加小红旗
  3. 剑指Offer——京东校招笔试题+知识点总结
  4. 【I2C】通用驱动i2c-dev分析
  5. postfix邮件管理
  6. 实战 本地服务器Confluence 7.13部署 一篇就够(从0开始安装配置 Debian11 + Mysql + Java)超详细
  7. 解析锂电池的充电的整个过程!
  8. 给家人们整无语了!教你用Python绘制流汗黄豆
  9. Android 8源码目录结构详解
  10. SIP 协议格式简介