【转】JPG打包压缩后比原来尺寸还大
作者:刘源
链接:https://www.zhihu.com/question/40371280/answer/86262934
来源:知乎
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
想用jpg的话,直接使用WWW加载jpg文件本身。加载好之后,WWW.texture 就是你要的贴图。
————————————————————————————————————
题主之前就是这个方法,后来为什么要改呢。对于题主的这种情况,即使与当前工作流不符,我也会认为有必要单写流程。优化项目时,由于内存、安装包大小的原因改资源结构是常有的事,有时候甚至要写专用的导出工具。
另外,AssetBundle开压缩不一定是坏事,个人目前实际项目中,Android上实测开压缩更快;而PC和IOS都是不压缩更快... 目前认为Android设备读写存储过慢。
————————————————————————————————————
扩展阅读:为什么Unity不支持jpg
为了满足实时渲染的需要,Unity会将你的图片预先编码为特定的显卡格式,常见的格式有DXT、ETC、PVRTC等。这些格式一般数据非常整齐,显卡会直接在显存中保持压缩格式,实时读取像素。对于各个目标平台,Unity有相应的支持格式列表可以手动选择(各平台不一样)。
这种编码速度挺慢的。首次打开一个工程时,Unity主要就是在做各种图片的编码,从jpg、psd等原始格式转换为显卡格式。大工程可达半个小时甚至更久。
常用的显卡压缩格式一般为4bps,就是0.5字节每像素。另外这些显卡压缩格式,一般未经过数学压缩,可以被zip等压缩算法再次压缩。
* 1280*720 RGB原始图片(RGB24):2.63M
* DXT1/ETC压缩: 0.43M (另外,PVRTC只支持1024这种2的幂尺寸的)
* AssetBundle开压缩模式(Unity使用LZMA算法,类似zip):上面数字的70%(照片)到25%(UI图集)。
jpg由于计算量大,所以不是一种显卡能支持的编码格式。Unity中,WWW可以加载jpg等格式的原始文件,获得RGB24这类未压缩的贴图。Unity帮你进行了jpg解码,但是不负责重新编码。
1. jpg算法 - 显卡不支持的算法
很遗憾,jpg并不是一种显卡支持的格式。
显卡压缩主要是为了解决显存限制的问题。显存是非常有限的,一张 2k*2k的图片不压缩的情况下高达12M,512M的显存只能放42张,所以压缩格式总是在显存中直接存储而不会解压的。显卡支持的格式,必须解码快,非常快,能够硬件直接从压缩格式中任意读像素。
jpg有很高的压缩比,1:20左右不会有明显的质量损失,你还可以往1:50甚至更高压。但是他的计算量过大。jpg的设计目标是实时整体解压缩,而不是实时随机访问。一方面jpg使用8x8的数据块作为编码单元,数据块过大;另一方面jpg使用了块变换编码,然后还对数字进行了压缩,挤掉了所有水分。读取单个像素都需要解压、反变换64个数据。
由于数字进行了压缩,zip对jpg是没有效果的。
jpg图片被等分成8x8的块,每块的64个像素首先变换到频率域(离散余弦变换),然后降低高频质量甚至丢弃一些过小的数据(称为量化),最后将剩下的数据压缩成一个串。精髓就在于,图片的主要信息来自于低频数据,高频数据精度下降一些一般看不出来。jpg这条路子也是当前视频编码的基石之一。
解码任何一个像素时,都需要读取对应块的全部数据流,解压缩到频率域,然后再反编码到64个像素,这样才能读出一个像素。可以想象其计算量。
2. 显卡支持的压缩格式
DXT、ETC、PVRTC的算法可以认为是步步进化的。这篇文章介绍了更早的蛮荒时代(DreamCast那个时代)的实时解压算法,有兴趣可以看看。
我们以最简单的 DXT1 为例。DXT1认为不透明图片可用 4x4的小块糊弄一下人的眼睛,每个4x4小块只有2个颜色,以及他们的两个中间色.... 一共就4个颜色!还特么有俩个是插值的,不知道你们感觉怎么样。解码非常直接,读号,两个颜色插值,结束。
这个简单的算法获得了极大的成功,随后被微软买了,变成DirectX的御用格式。而且后面的算法都是这类思想:
* 数据块小
* 不做块变换,只用简单的插值、加减(jpg是64个数的变换) --- 极大减少计算量
* 不做数学压缩,所以定长,可以直接寻址 --- 再次减少计算量,以及数据依赖性
由于不做数学压缩,所以这类图片都可以被zip等算法大幅度再次压缩。
顺便一提,这类算法的编码比较耗时,而且结果不唯一。以DXT1为例,我们有16个像素,现在要挑两个颜色,以及他们连线上的2个中间色代替这16个像素,哪两个颜色最合适呢?显然计算量就上来了,选择也很多。
最后,jpeg和显卡压缩算法都是有损压缩。就画质来说,jpeg远远胜出。jpeg在1:10时几乎看不出与原图的差异,1:20时仍有极好的效果;而显卡贴图压缩1:6左右就有明显画面损失。实际观察,美术一般能接受写实模型纹理的压缩,同时一般难以接受UI压缩的效果,特别是锐利的斜线和弧线,条状物,或者半透明渐变都容易出现瑕疵。对于题主的情况,看起来很像背景图之类的,确实可以考虑使用jpeg。
的答案已经覆盖了原因。简单来说就是AssetBundle里的格式是为了让显卡能用,jpg是为了让空间更小。
补充一点,最近的情况其实在改变,D3D12支持用jpeg作为纹理格式,虽然(应该)还没有驱动支持了这一点。GPU,尤其是移动GPU,是可以硬件解码jpeg的,但没回馈给programmable pipeline的texture sampler。把这条路打通就能直接都jpeg。
【转】JPG打包压缩后比原来尺寸还大的更多相关文章
- ASP.NET MVC 4 RC的JS/CSS打包压缩功能 (转载)
ASP.NET MVC 4 RC的JS/CSS打包压缩功能 打包(Bundling)及压缩(Minification)指的是将多个js文件或css文件打包成单一文件并压缩的做法,如此可减少浏览器需下载 ...
- (转)ASP.NET MVC 4 RC的JS/CSS打包压缩功能
转自:http://www.cnblogs.com/shanyou/archive/2012/06/22/2558580.html 打包(Bundling)及压缩(Minification)指的是将多 ...
- ASP.NET MVC 4 RC的JS/CSS打包压缩功能
打包(Bundling)及压缩(Minification)指的是将多个js文件或css文件打包成单一文件并压缩的做法,如此可减少浏览器需下载多个文件案才能完成网页显示的延迟感,同时通过移除JS/CSS ...
- 在MVC中使用Bundle打包压缩js和css
第一步:安装 安装“System.Web.Optimization”:在中“NuGet”中搜索 安装. 第二步:配置 配置“Views”目录下的“web.config”文件增加“System.Web. ...
- vue使用webpack压缩后体积过大要怎么优化
vue使用webPack压缩后存储过大,怎么优化 在生产环境去除developtool选项 在webpack.config.js中设置的developtool选项,仅适用于开发环境,这样会造成打包成的 ...
- 【转】ASP.NET MVC 4 RC的JS/CSS打包压缩功能
原文链接:http://www.cnblogs.com/shanyou/archive/2012/06/22/2558580.html 打包(Bundling)及压缩(Minification)指的是 ...
- webpack打包后不能调用,改用uglifyjs打包压缩
背景: 项目基于原生js,没用到任何脚手架和框架,但也需要打包压缩. 项目的js中声明了一些全局变量 供其他js调用. 这时候如果用webpack打包,基于webpack特性,会嵌套一层大函数,会将j ...
- linux下如何打包压缩?解包解压?.tar文件.gz文件
===文件打包.压缩 ==打包 tar [root@521478.com]# tar -cvf etc1.tar /etc //c创建 v详细 f打包后文件名 [root@521478.com]# t ...
- Linux打包压缩.md
Linux下打包压缩命令 下面学习一下压缩和打包的相关命令,首先得先明确两个概念,即:压缩和打包 .我们实际使用中一般是打包和压缩结合的使用,为了学习下面简要的介绍一下压缩文件或目录的命令. 压缩:将 ...
随机推荐
- Java HashMap的工作原理
面试的时候经常会遇见诸如:”java中的HashMap是怎么工作的”.”HashMap的get和put内部的工作原理”这样的问题. 本文将用一个简单的例子来解释下HashMap内部的工作原理. 首先我 ...
- xtrabackup三种备份和还原(一)
写这边博客心情不是太美好(博客已经停更2个多月了,实在是没心情学习新东西.2018我的黑暗年,呵呵)好了,不废话了,本文没有任何原理的部分,我也是刚开始接触xtrabackup这个工具.本文应该是一个 ...
- Java中private、protected、public和default的区别 (转)
本文内容转载自: https://www.cnblogs.com/jingmengxintang/p/5898900.html public: 具有最大的访问权限,可以访问任何一个在classpath ...
- error: 'ENOSYS' undeclared (first use in this function)
/************************************************************************ * error: 'ENOSYS' undeclar ...
- HDU1502 Regular Words DP+大数
要是c语言可以和java一样写大数就好了,或者我会写重载就好了,最后还是只能暴力一把. 开始写的记忆化搜索,然而n=10就超过LL了 #include<cstdio> #include&l ...
- python的继承顺序
python的继承顺序 python 创建类时分为新式类和旧式类 class A: # 经典类 def __init__(self): pass # 新类,可以在这里加 __metaclass__ = ...
- Rotor envoy control plane 简单试用
rotor 基于golang 的envoy xds 服务,支持多种集成方式: k8s consul aws dc/os demo试用docker 以及consul 进行环境运行 下载demo 可以试用 ...
- centos7上docker安装和使用教程
Docker 是一个创建和管理 Linux 容器的开源工具.容器就像是轻量级的虚拟机,并且可以以毫秒级的速度来启动或停止.Docker 帮助系统管理员和程序员在容器中开发应用程序,并且可以扩展到成千上 ...
- Quick guide for converting from JAGS or BUGS to NIMBLE
Converting to NIMBLE from JAGS, OpenBUGS or WinBUGS NIMBLE is a hierarchical modeling package that u ...
- Spring容器初始化数据(数据库)BeanPostProcessor的应用
1.目的:在Spring启动的时候加载在数据库保存的配置信息,一方面杜绝随意修改,一方面方便管理 2.BeanPostProcessor是Spring提供的一个方法通过implements方式实现 会 ...