腾讯PAG动效工具解析

什么是PAG?

1、背景

在终端 APP 中,动画非常常见,它可以辅助视觉制造焦点,同时也可以让用户交互更加顺滑,但动画的实现却是设计师和研发群体的一个痛点。如何辅助设计师设计高性能炫酷的动画、如何将设计师设计的动画准确无误的还原到终端 APP 上是业界不断探索和解决的问题。

2、简介

PAG是由腾讯推出的一套完整的动效工作流解决方案,目标是降低或消除动效相关的研发成本,能够一键将设计师在AE中制作的动效内容导出成素材文件,并快速上线应用于几乎所有的主流平台。

设计师在 AE 上设计出动画后,可以通过导出插件导出 Pag 文件,同时可以在桌面端预览工具中实时预览效果,还可以通过桌面端进行性能检测。PAG 可以支持 Android、iOS、web、mac OS、Windows 和 Linux,涵盖了业界常用的终端平台,支持 AE 动画实时渲染、运行时编辑。

官方网站:https://pag.art/

PAG动效的特点

1、高效的文件格式

PAG动效文件采用了二进制的数据结构来存储AE动效信息。二进制数据结构能够非常方便的单文件集成任何资源,如位图、音频、视频资源等,实现单文件交付。同时二进制数据结构不需要像JSON一样处理字符串匹配问题,解码速度可以快90%以上。另外在压缩率方面,相比JSON,二进制数据结构可以跳过Key的内容,只存储Value,这样能节省大量空间。如果只做到这个程度,其实就是Protocol Buffers这种通用的二进制序列化方案的原理。为了进一步压缩数据,结合AE动效数据的特征,利用时间轴属性存在默认值和AE动效中存在大量连续整形、Float类型数据的特点,PAG采用了动态比特位压缩的技术,实现了比特位级别的存储和读取,大大减少了存储的冗余空间。

经过一系列的压缩策略,导出相同的 AE 动效内容,在文件解码速度和压缩率上均大幅领先于同类型方案。采用可扩展的二进制文件格式,可单文件集成包含图片、音频等任意设计资源。

与Lottie动画对比,可以看到相同的动效内容平均PAG只有Lottie文件的56%大小。如果不进行zip压缩,差距还会更大。

PAG格式规范:https://pag.art/docs/pag-spec.html

2、AE 特性全面支持

当前最好的动画设计软件是 Adobe After Effects(简称 AE),设计师使用AE软件设计动画后可以采用矢量导出,矢量导出方式优势就是文件极小,并且可以运行时编辑动效的内容。但这种方式注定无法支持所有AE特性,因为有很多的AE效果在有桌面显卡的情况下,都要走一个进度条才能预览,在移动端是没有可能做到实时渲染的。这也导致在实际的生产过程中,设计师有很多的复杂动效,都无法用矢量模式导出出来,这样会极大限制设计师的创意发挥。而传统的序列帧导出方式,运行时又无法编辑,文件也相对较大。

PAG在纯矢量导出方式上支持更多 AE 特性的同时,还引入了BMP预合成结合矢量的混合导出能力,实现支持所有 AE 特性的同时又能保持动效运行时的可编辑性。

① 矢量特性能力的支持

在纯矢量的导出模式下,无论是哪种实现方案,在众多的的AE特性面前,都只支持将有限的AE特性导出渲染。和 Lottie、SVGA 实现不同的是,PAG 不依赖平台端渲染接口,可以实现各平台的渲染一致性。

② BMP 预合成–全 AE 特性支持

PAG 新增了 BMP 预合成的导出方式,支持导出所有 AE 特性,适用于不可编辑的场景PAG,支持将特定图层截图导出成透明视频,实现了对于所有AE特性导出的支持。

③ 矢量和序列帧混合导出

设计师可以主动标记哪些图层使用序列帧导出,例如不需要编辑并且有复杂的动效,而需要编辑的图层继续用简单的矢量方式导出。从而实现支持所有的AE特性又能保持运行时的编辑性。

3、完善的动画工作流

通常设计师输出动效给开发都是直接 AE 导出就给开发了,很少去关注动效的性能问题,并且每次想要尝试不同素材动画效果时,需要在 AE 中调试输出后在去看效果,导致设计成本浪费。

采用 PAG 进行动效设计的话,我们在 AE 中调试好输出动效后,可以直接在 PAG 桌面端进行查看,在桌面端我们可以快速替换动效中的图片素材或文案来查看效果,同时可以通过性能面板查看当前动效的性能,方便设计师进行针对性优化。

桌面 预览工具:PAGViewer

桌面端预览工具 PAGViewer 不仅仅支持预览 PAG 文件效果,还支持编辑文本和填充占位图,无需等到上线便可预览线上效果

AE 导出 插件:PAGExporter

设计师在 AE 中完成动效设计后,需要通过导出插件 PAGExporter 导出 PAG 文件

③ 预览可编辑:

③ 预览时性能监测

PAGViewer确保了渲染结果跟移动端完全一致,这样设计师可以直观地看到移动端的展示效果,而不需要上线来回确认。同时提供性能检测面板,帮助开发工程师根据素材量化的性能指标进行优化。

以上各面板参数说明见:https://pag.art/docs/profiler.html

4、性能强文件小

PAG 采用了二进制的数据结构来存储动画信息。二进制数据结构能够非常方便的单文件集成任何资源,在解码速度上比 Lottie 所使用的 JSON 文本数据快几十倍,在性能方面,PAG 的实时渲染性能平均可以达到 Lottie 的 1.5 到 2.5 倍左右。

而在文件大小上,PAG 通过利用动画文件本身的特点,获得了极高的压缩率。通过跳过大量默认值的存储,使用比特位来紧凑存储,相同动画内容可以比同类型方案平均减少 50% 左右的文件大小。

整体对比:

Android侧开发接入

基本要求

  • 支持 android 4.4 及以上系统
  • 推荐使用 gradle 3.0 及以上版本编译

社区基础版本 com.tencent.tav:libpag:4.2.41

在 root 工程目录下面修改 build.gradle 文件,增加** mavenCentral()**

buildscript {repositories {mavenCentral()}dependencies {classpath 'com.android.tools.build:gradle:3.2.1'}
}

app 的 gradle 文件 app/build.gradle,添加 libpag 的库依赖

dependencies {//基础版本,如需保持最新版本,可以使用 latest.release 指代implementation 'com.tencent.tav:libpag:latest.release'}

基础使用:

RelativeLayout backgroundView = findViewById(R.id.background_view);
PAGView pagView = new PAGView(this);
pagView.setLayoutParams(new RelativeLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
backgroundView.addView(pagView);
PAGFile pagFile1 = PAGFile.Load(getAssets(), "replacement.pag" );
pagView.setComposition(pagFile1);
pagView.setRepeatCount(0);
pagView.play();

替换文本:

PAGFile pagFile = PAGFile.Load(getAssets(), "test2.pag" );
// 替换文本的代码
PAGText textData = pagFile.getTextData(0);
textData.text = "replacement test" ;
pagFile.replaceText(0, textData);
pagView.setComposition(pagFile);
pagView.setRepeatCount(0);
pagView.play();

替换图片:

PAGFile pagFile1 = PAGFile.Load(getAssets(), "replacement.pag" );
// 替换图片
pagFile.replaceImage(0, createPAGImage());
pagView.setComposition(pagFile1);
pagView.setRepeatCount(0);
pagView.play();private PAGImage createPAGImage() {AssetManager assetManager = getAssets();InputStream stream = null;try {stream = assetManager.open( "test.png" );} catch (IOException e) {e.printStackTrace();}Bitmap bitmap = BitmapFactory.decodeStream(stream);if (bitmap == null) {return  null;}return PAGImage.FromBitmap(bitmap);
}

同时展示多个PAGFile:

pagComposition = PAGComposition.Make(width, height);
float itemWidth = width / 5;
float itemHeight = 300;
for (int i = 0; i < 20; i++) {pagComposition.addLayer(getPagFile(i / 5,  i % 5, i + ".pag" , itemWidth, itemHeight));
}
pagView.setComposition(pagComposition);
pagView.setRepeatCount(0);
pagView.play();

PAGImageView使用:

int ids[] = {R.id.pagView1, R.id.pagView2, R.id.pagView3, R.id.pagView4, R.id.pagView5,R.id.pagView6, R.id.pagView7, R.id.pagView8, R.id.pagView9, R.id.pagView10,R.id.pagView11, R.id.pagView12, R.id.pagView13, R.id.pagView14, R.id.pagView15,R.id.pagView16, R.id.pagView17, R.id.pagView18, R.id.pagView19, R.id.pagView20,R.id.pagView21, R.id.pagView22};
for (int i = 0; i < ids.length; i++) {PAGImageView view = findViewById(ids[i]);view.setPath( "assets://" + (i + 1) + ".pag" );view.setRepeatCount(-1);view.play();
}

PAGImageView说明:

PAG 4.2 版本开始增加了针对 UI 场景的专用播放组件 PAGImageView,可以有效绕开 PAGView GPU 实时渲染方案在 UI 场景下劣势。尤其是对 UI 列表或同一页面中同时播放多个 PAG 文件的场景,可以显著降低内存占用同时提升渲染性能。其主要原理是充分利用了磁盘缓存,在渲染当前帧的同时,也将当前帧的渲染数据缓存到本地。单个动效文件在整个生命周期中用户只会看到一次短暂基于 GPU 实时渲染的画面,后续都是直接读取高速的磁盘缓存来呈现,并且即使重启 App 后缓存也仍然有效。从而降低整个渲染过程中因为 GPU 实时渲染而引入的额外基础开销。另外由于 PAGImageView 跟 UI 框架之间并没有 GPU 桥接层,天然的能够高性能混合,也就无需处理任何额外的合并播放逻辑。

PAGImageView适用场景:

如果 PAGImageView 渲染的尺寸较大且 PAG 文件 时长较长,如手机全屏这种情况,会占用较大的磁盘空间做缓存,可能一个 PAG 文件 缓存下来就要几百 MB,目前磁盘缓存默认占用最大磁盘空间为 1GB,如果这样的情况较多,会不断触发清理缓存逻辑,不但不会提升性能,反而使性能变差。

PAGImageView 适用于 UI 列表 或一个页面中含有多个小尺寸 View 的场景,这种场景下渲染的尺寸较小,一个 PAG 文件 缓存完占用的磁盘空间也就几十 MB,渲染使用的时候会不断命中缓存,从而提升性能。其余场景我们还是推荐使用 PAGView。

更多API说明及使用方式见:https://pag.art/docs/api-instructions.html

官方Demo下载:https://pag.art/docs/pad-demo-download.html

Lottie迁移至PAG:https://pag.art/docs/SDK-migration.html

谁在使用…

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

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

自托管端口管理系统Portall

老苏一直在折腾各种开源软件&#xff0c;但总是记不清哪些应用占用了哪些端口&#xff0c;每次都是先随机想一个端口&#xff0c;然后在笔记中搜索&#xff0c;看有没有被占用过。Portall 就是用来解决老苏遇到的这种情况的&#xff0c;当然&#xff0c;excel 也是可以的 &…

十分钟“手撕”七大排序

前言&#xff1a;可以通过目录来找你需要的排序的源代码。先是解释底层原理&#xff0c;后附带代码。 目录 稳定的概念 一、插入排序 二、希尔排序 三、选择排序 四、堆排序 五、冒泡排序 六、快速排序 七、归并排序 八、排序总结 额外&#xff1a;计数排序 稳定的…

Qt MV架构-委托类

一、基本概念 与MVC模式不同&#xff0c;MV视图架构中没有包含一个完全分离的组件来处理与用户的交互。 一般地&#xff0c;视图用来将模型中的数据显示给用户&#xff0c;也用来处理用户的输入。为了获得更高的灵活性&#xff0c;交互可以由委托来执行。 这些组件提供了输入…

gradle学习及问题

一、下载安装 参考&#xff1a;https://blog.csdn.net/chentian114/article/details/123344839 1、下载Gradle并解压 安装包&#xff1a;gradle-6.7-bin.zip 可以在idea的安装目录查看自己适配的版本 路径&#xff1a;D:\IDEA2021.3\plugins\gradle\lib 下载地址&#xff1a…

16_网络IPC2-寻址

进程标识 字节序 采用大小模式对数据进行存放的主要区别在于在存放的字节顺序&#xff0c;大端方式将高位存放在低地址&#xff0c;小端方式将高位存放在高地址。 采用大端方式进行数据存放符合人类的正常思维&#xff0c;而采用小端方式进行数据存放利于计算机处理。到目前…

python用selenium网页模拟时xpath无法定位元素解决方法2

有时我们在使用python selenium xpath时&#xff0c;无法定位元素&#xff0c;红字显示no such element。上一篇文章写了1种情况&#xff0c;是包含iframe的&#xff0c;详见https://blog.csdn.net/Sixth5/article/details/140342929。 本篇写第2种情况&#xff0c;就是xpath定…

Linux 线程初步解析

1.线程概念 在一个程序里的一个执行路线就叫做线程&#xff08;thread&#xff09;。更准确的定义是&#xff1a;线程是“一个进程内部的控制序列。在linux中&#xff0c;由于线程和进程都具有id,都需要调度等等相似性&#xff0c;因此都可以用PCB来描述和控制,线程含有PCB&am…

人类或是低等生物?

自工业革命以来&#xff0c;人类对自然资源的消耗日益加剧&#xff0c;引发了对未来可持续性的深刻担忧。然而&#xff0c;一项振奋人心的发现为人类提供了新的希望——一颗名为LHS 1140 b的超级地球&#xff0c;它位于距离地球约48光年的鲸鱼座&#xff0c;由詹姆斯韦布空间望…

uniapp字符串转base64,无需导入依赖(多端支持)

使用示例 import { Base64Encode, Base64Decode } from "@/utils/base64.js" base64.js const _keyStr = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=";export const Base64Encode = (text)

Qt Creator的好用的功能

&#xff08;1&#xff09;ctrlf&#xff1a; 在当前文档进行查询操作 &#xff08;2&#xff09;f3: 找到后&#xff0c;按f3&#xff0c;查找下一个 &#xff08;3&#xff09;shiftf3: 查找上一个 右键菜单&#xff1a; (4)f4&#xff1a;在…

使用vcXsrv可视化pcl文件

1、下载vcXsrc程序 2、按下面步骤配置 3、按上面操作后&#xff0c;在运行菜单就能看到它在运行了 4、去wsl中配置&#xff0c;即设置环境变量 vim ~/.bashrc # 设置连接windows的VcXsrv export DISPLAY192.168.1.100:0.0 #&#xff08;192.168.1.100是我windows的ip&#x…

信创学习笔记(四),信创之数据库DB思维导图

创作不易 只因热爱!! 热衷分享&#xff0c;一起成长! “你的鼓励就是我努力付出的动力” 一. 信创学习回顾 1.信创内容 信创内容思维导图 2.信创之CPU芯片架构 信创之CPU芯片架构思维导图 3.信创之操作系统OS 信创之操作系统OS思维导图 二. 信创之国产数据库DB思维导图 …

LAST_INSERT_ID使用方法-(DM8达梦数据库)

LAST_INSERT_ID使用方法 - DM8达梦数据库 1 示例 11.1 创建表1.2 结果集 2 示例 22.1 创建表2.2 结果集 3 达梦数据库学习使用列表 1 示例 1 1.1 创建表 DROP TABLE AT240715; CREATE TABLE "SYSDBA"."AT240715" ( "ID" INT PRIMARY KEY AUTO_…

Autosar Dcm配置-0x28服务ComControl-基于ETAS软件

文章目录 前言DcmDcmDsdDcmDspBswMBswMModeRequestPortBswMModeConditionBswMLogicalExpressionBswMActionBswMActionListBswMRule总结前言 0x28服务主要用来控制非诊断报文的通讯,一般在刷写预编程过程中,用来禁止APP的通信报文,可以减少总线负载率,提高刷写成功率。本文…

数据结构之线性表表示集合详解与示例(C,C#,C++)

文章目录 基本特征线性表的特点&#xff1a;线性表的表示方法&#xff1a;C、C#和C语言如何实现一个线性表表示集合1. C实现2. C#实现3. C实现 总结 线性表是计算机数据结构中的一个基本概念&#xff0c;它是一种最简单的抽象数据类型。在线性表中&#xff0c;数据元素之间的关…

pip install安装第三方库 error: Microsoft Visual C++ 14.0 or greater is required

原因&#xff1a; 在windows出现此情况的原因是pip安装的库其中部分代码不是python而是使用C等代码编写&#xff0c;我们安装这种类型的库时需要进行编译后安装。 安装Microsoft C Build Tools软件&#xff0c;但这种方式对于很多人来说过于笨重。&#xff08;不推荐&#xf…

VUE:跨域配置代理服务器

//在vite.config。js中&#xff0c;同插件配置同级进行配置server:{proxy:{"/myrequest":{//代理域名&#xff0c;可自行修改target:"https://m.wzj.com/",//访问服务器的目标域名changeOrigin:true,//允许跨域configure:(proxy,options) > {proxy.on(&…

【Django+Vue3 线上教育平台项目实战】登录功能模块之短信登录与钉钉三方登录

文章目录 前言一、几个关键概念1.HTTP无状态性2.Session机制3.Token认证4.JWT 二、通过手机号验证码登录1.前端短信登录界面2.发送短信接口与短信登录接口3.Vue 设置interceptors拦截器4. 服务端验证采用自定义中间件方式实现5. 操作流程及效果图如下&#xff1a; 三、通过第三…

Flychat:跨越距离的心灵桥梁

在当今这个数字化时代&#xff0c;人们的沟通方式变得越来越多样化&#xff0c;而移动设备的普及更是极大地推动了这一趋势。我们几乎可以随时随地与他人进行交流&#xff0c;分享生活的点滴。然而&#xff0c;在享受这些便捷的同时&#xff0c;我们也时常会遇到一些小困扰——…

Rust 使用 panic! 还是不用 panic!

使用 panic! 还是不用 panic! 那么&#xff0c;该如何决定何时应该 panic! 以及何时应该返回 Result 呢&#xff1f;如果代码 panic&#xff0c;就没有恢复的可能。你可以选择对任何错误场景都调用 panic!&#xff0c;不管是否有可能恢复&#xff0c;不过这样就是你代替调用者…