一般的压缩方案

做移动平台,终究都是要考虑纹理压缩的问题

IOS/PVR平台上一般会选用PVRTC格式,这个格式压缩还是很给力。

Android上设备种类很多,支持的格式各有不同。如果平台能支持下载前检测设备来区分下载的APK,我们可以选择相应的压缩格式。但是很多平台都只要一个APK,我们就只能选择最稳妥的ETC1+Alpha方案了。

这个方案用过的应该都知道并不是特别好,首先肯定要生成两张图,然后压缩比还不错,但是压缩质量就有点不行了。在普通的纹理上用还可以,但是在UI这种要足够清晰的地方就有些尴尬。

思路

我想要解决的问题是怎么在保证一定的压缩比情况下,尽可能保证图像质量,给ETC1+Aplha找一个替换的方案。

一个彩色图片中到底那些对清晰度感受更重要?

一般的RGB图,三个通道是等价的,要压缩一起压缩。要损品质一起损,有没有其他的图片表达方式更适合压缩?

我做了这个使用YCrCb 2020标准的YUV转换,我觉得还可以,就是下图第二个。

效果图

第一次尝试,HSV方案

HSV就是用色调(H),饱和度(S),明度(V)来表示色彩的方式,具体的介绍HSV百度百科。在这种表达方式中保证H的精度就可以在最终的图上保证相当的显示效果,于是我们将其他通道都压缩一半的分辨率。对一个RGBA图来说转换成HSVA图能有7/16的压缩比,不是很高,但是已经是可以接受的了。

然后我们实验一下……

简直辣眼睛,这是什么鬼

将过滤模式改为point,之后这个现象变成了一些紫色的斑点,而且颗粒感好强。

进一步研究发现这时因为色相H的采样过滤造成的,色相一般是这个样子

展开成直线就变成了这样

最终我们时将h存入图片的一个通道上,也就是i这个直线的取值变成了0~1之间。然后我们从图上采样会发生什么呢?

设想像素A是偏黄的红色,取值应该是0.05左右。相邻的一个像素B是偏紫的红色,去只是0.95左右。

这时会发生什么?在双线性采样的时候中间的屏幕像素会被插值……然后两个像素中间就会变成一个小小的从红色到红色的彩虹

显然我们是不能接受point采样的效果,我们还得想想别的办法。

YUV方案

YUV就是使用色差进行颜色编码,由亮度信号Y和两个色差新号B-Y(即U)、R-Y(即V)组成。 YUV百度百科

Y这个亮度实际上是由RGB三个通道叠加出来的,显然保证Y基本就保证了清晰度。

这个YUV最早是给电视用的,经过了很多年发展,出了几代标准,更多的覆盖了色度空间上的颜色范围。

内圈是HDTV709,外圈是UHDTV2020

那么显然我们就用2020标准就好了。

实现YUV

RGBA图转换到YUVA图的工具

第一步就是如何生成YUVA图,这个显然让美术提供会有些强人所难,我们需要由一个自动化工具来做这件事情。

这种转换就是一次两个坐标系之间的坐标转换,重点就是生成正确的转换矩阵。这个矩阵要怎样生成我是靠wiki来解决的,感谢wiki。如果有兴趣可以自己去搜一下,代码里的注释也写了网址。

基本的流程:读取图片,转换成YUV,分通道压缩,生成纹理。

最后就是这个样子,反正能看代码,就不细说了。

最后这个invert matrix是为了写shader方便弄的,就是反转换矩阵。总不能在shader里面还每次都算一遍这个矩阵。

注意:其实还需要一个PostProcesser脚本,将所有生成的YUV图转成apha8格式,毕竟我们只需要一个通道。

显示Shader

这就真没啥可说的,分别采样4个图,然后用反转矩阵做一下乘法,就完事了。

可能的优化

采样4次,也是很废。实际上是可以变成采样两次的,Y一个alpha8图,UVA用一个RGB图。采样两次,压缩比还是7/16。

矩阵现在是写死在shader里面,也可以改成参数的,应该能快一点。

YUVA生成工具甚至可以改为之间修改material的,一劳永逸。

工程代码

git链接

换一个思路压缩图片,RGB转YUV的更多相关文章

  1. 推荐一个用于压缩图片的JS插件:localResizeIMG

    惯例,先贴传送门:https://github.com/think2011/localResizeIMG 首先说到,为嘛要压缩图片,这需求一般出现在需要上传照片(尤其是移动端)的情况下,现在手机拍出来 ...

  2. 弯道超车,换一个思路,避免addEventListener为同一个元素重复赋予事件

    addEventListener可以给同一个元素赋予多次同一个事件. 执行一次,就多一次事件效果.这不是我想要的. window.onload = function(){ var box = docu ...

  3. C# Winform版批量压缩图片程序

    需求 上周,领导给我分配了一个需求:服务器上的图片文件非常大,每天要用掉两个G的大小的空间,要做一个自动压缩图片的工具处理这些大图片.领导的思路是这样的: 1)打开一个图片,看它的属性里面象素是多少, ...

  4. 使用Python轻松批量压缩图片

    在互联网,图片的大小对一个网站的响应速度有着明显的影响,因此在提供用户预览的时候,图片往往是使用压缩后的.如果一个网站图片较多,一张张压缩显然很浪费时间.那么接下来,我就跟大家分享一个批量压缩图片的方 ...

  5. 多媒体编程基础之RGB和YUV

    一.概念 1.什么是RGB? 对一种颜色进行编码的方法统称为“颜色空间”或“色域”.用最简单的话说,世界上任何一种颜色的“颜色空间”都可定义成一个固定的数字或变量.RGB(红.绿.蓝)只是众多颜色空间 ...

  6. 关于RGB转换YUV的探讨与实现

    最近在Android手机上使用相机识别条形码工作取得了比较理想的进展,自动识别功能基本完成,然而在手动识别指定条形码图片时遇到困难,由于Zxing开源Jar包识别图片的颜色编码式为YUV,而普通的图片 ...

  7. 【厚积薄发】Crunch压缩图片的AssetBundle打包

    这是第133篇UWA技术知识分享的推送.今天我们继续为大家精选了若干和开发.优化相关的问题,建议阅读时间10分钟,认真读完必有收获. UWA 问答社区:answer.uwa4d.com UWA QQ群 ...

  8. 视音频数据处理入门:RGB、YUV像素数据处理

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

  9. [转载] 视音频数据处理入门:RGB、YUV像素数据处理

    ===================================================== 视音频数据处理入门系列文章: 视音频数据处理入门:RGB.YUV像素数据处理 视音频数据处理 ...

随机推荐

  1. mongo链接solr的过程与问题

    我的环境: 1:ubunt 16 2:mongodb 2.6.1 3:solr 6.3 4:JDK 1.8 准备过程: 1:安装mongo-connector #pip install mongo-c ...

  2. 让LinqToSQL使用Web.Config中的链接字符串(修改Settings.Designer.cs)

    [global::System.Configuration.ApplicationScopedSettingAttribute()] [global::System.Diagnostics.Debug ...

  3. c#读写文件

    1.添加命名空间 System.IO; System.Text; 2.文件的读取 (1).使用FileStream类进行文件的读取,并将它转换成char数组,然后输出. byte[] byData = ...

  4. ABAP 弹出对话框

    一组有用的用户交互窗口函数 显示多条消息 SAP系统用的是这个函数:C14Z_MESSAGES_SHOW_AS_POPUP POPUP_TO_CONFIRM_LOSS_OF_DATA 显示有YES/N ...

  5. js中的break ,continue, return (转)

    面向对象编程语法中我们会碰到break ,continue, return这三个常用的关键字,那么关于这三个关键字的使用具体的操作是什么呢?我们在使用这三关键字的时候需要注意和需要理解的规则是什么呢? ...

  6. ion-header-bar

    ion-header-bar 指令声明一个标题栏元素,标题栏总是位于屏幕顶部 它有两个同级的可选属性 align-title:设置标题文字的对齐方式.允许值:left|right|center no- ...

  7. 评价qq拼音输入法

    我目前正在使用qq拼音输入法,从人机交互设计方面,我对qq输入法从用户界面.记住用户选择.短期刺激和长期使用的好处坏处.不让用户犯简单错误这四个方面进行了评价. 1.从用户界面方面: qq输入法用户界 ...

  8. 转载《android:scaleType属性》

    在网上查了好多资料,大致都雷同,大家都是互相抄袭的,看着很费劲,不好理解,自己总结一下,留着需要看的话来查找. 代码中的例子如下: <ImageView android:id="@+i ...

  9. 零基础如何自学MySQL数据库?

    作者:姜健链接:https://www.zhihu.com/question/34840297/answer/67536521来源:知乎著作权归作者所有,转载请联系作者获得授权. 本人是个活生生的例子 ...

  10. memory corruption

    今天遇到了一个比较弱的问题,但是涉及到一些东西,所以记录一下. 问题表现为,系统BOSD,在析构函数进行free的时候,有的时候是在使用buffer的过程中就BSOD. 之前是怀疑因为分配的是page ...