iOS开发iOS-swiftiOS收藏

[iOS 开发] 图文快照分享的实现

2017-05-30  本文已影响1069人  ShannonChenCHN

前言:『图文快照』是指将一组图片和文字,进行排版组合,最终生成一张长图片。长图片(长微博)最早是在微博中出现的,后来在其他一些应用中(简书、小红书、百度地图)也看到了分享长图片的功能,另外还有些专门制作长图片的工具,比如锤子便签、Zine。

目录

0.背景介绍
1. 需求分析
2. 实现思路
3. 实现过程
4. 单元测试
5. 几个问题
6. 参考资料

0.背景介绍

任何有实际意义的创新都不是凭空想象出来的(这不废话么~)。长图片在微博中出现的起因是当时微博中文字长度不得超过140字,所以当文字比较多时就可以转为图片来发布。 微博作为碎片化时代的代表,本身带有“快餐化”、“碎片化”的标签,长图片的出现,在一定程度上与短微博形成了互补,现在我们经常可以看到一条这样的微博:一段短文描述 + 链接 + 一张内容详尽的长图片。而且,以图片代替文字在某种程度上可以躲过“河蟹”。

微博长图.png

所以,长图片给我们带来的好处显而易见——快好省,可以让用户用最少的代价,更快地,看到更多的内容。

1. 需求分析

需求:点击分享菜单中的“朋友圈快照”按钮,将要分享的社区图文帖转成长图片(图片中的内容从上到下,依次为品牌 logo、用户信息、文字、图片、点赞、二维码信息),然后分享到朋友圈。
以前分享到朋友圈的是这条帖子的链接,用户看到的只是一个标题和 icon,需要点击跳转再加载网页才能看到内容,而现在采用长图的方式,可以让用户更直观、更快地看到分享的内容,更利于传播。

技术分析:这个需求的核心是图片,所以我们在生成图片时需要重点考虑的有两点:

生成并分享图文快照的过程

2. 实现思路

首先我们要考虑的是,如何把数据变成图片?
我们平时在开发过程中都是通过创建 view 来实现视觉效果的,所以我们可以从 UIView 入手——UIView->UIImage。我们可以通过 UILayer-renderInContext: 方法将 UIView 在 context 上进行图像内容渲染,然后再通过 UIGraphicsGetImageFromCurrentImageContext() 获取图片。

讨论:当然你也许会说,为什么不用 drawViewHierarchyInRect:afterScreenUpdates: 方法来生成图片,它比 -renderInContext: 方法效率要高啊,实际上drawViewHierarchyInRect:afterScreenUpdates: 不支持不可见的 view,也就是说,对于没有显示在屏幕上的 view,调用这个方法不起作用。

核心部分弄清楚之后,其他的就简单了,大概梳理一下,生成图文快照的主要流程如下图所示:

实现流程

3. 实现过程

具体的代码见 ShannonChenCHN/SCSnapshotManager,这里我们只讨论实现过程。

3.1 需要考虑的问题
3.2 一图胜千言
SCSnapshotManager 的实现原理

结合上面的示例图,一张快照的生成需要经历下面几个步骤:

3.3 Architecture
类名 功能
SCSnapshotManager 负责主线逻辑,串联各子逻辑(从生成二维码到分享快照),这里面的逻辑一般不怎么变动的
SCSnapshotProviderProtocol 所有 Provider 类需要遵循的协议,不论是要生成什么样的快照,主流程是不会有什么变化的,变化的是 Provider,不同的需求(数据、逻辑、展示)对应不同的 Provider,所以在 Example 中,商户快照对应有一个 SCSnapshotMerchantProvider,图文帖快照对应也有一个 SCSnapshotPostProvider,每个具体的 provider 只需要遵守 <SCSnapshotProvider> 协议,并实现其中的方法即可:① 转换 Model,② 拼装图片下载 URL,以提供给 SCSnapshotImageDownloader 下载,③ 拿下载好的图片来创建 view,④ 其他强业务逻辑,比如埋点
SCQRCodeGenerator 二维码生成器,根据一个字符串生成一张二维码图片
SCSnapshotImageDownloader 图片下载器,因为要下载的是多张图片,而且还要考虑到分组展示的情况,所以这里我们将要下载的图片 URLs 包装成二维数组传入,下载完成后,得到一个装有图片的二维数组
SCSnapshotGenerator 将 view 转成 image

4. 单元测试

4.1 单元测试的目的
4.2 怎么测

具体测试内容见 ExampleProject

5. 几个问题

从评测结果中的内存峰值和压缩时间来看,显然后者更好。

从微信中导出的图片格式来看,应该是 JPG 的。

综合考虑图片展示效果和图片体积大小,640px 的宽度已经足够了。因为不论是iPhone 5 还是 iPhone 6Plus 生成的图片,都是640 px 宽度的,而且不需要在屏幕上展示,所以用于生成快照的 view 的图片素材不管是 @2x,还是 @3x,都是一样的大小。

从效率和性能上看,显然选第二种更好,因为绘制是比较耗性能的。 评测结果证明也是如此。

6.参考资料


Contact Me
上一篇下一篇

猜你喜欢

热点阅读