作者:刘源
链接: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 优点:文件小,磁盘占用少。
缺点:1,压缩算法太复杂,解压费时,不被GPU硬件解压支持;2,解压时(后)占用内存比其它格式(ETC,PVRTC)内存占用大。
ETC格式或PVRTC格式虽然文件大一些,多占用了一些存储空间,但其解压是被GPU直接支持的硬件瞬间解压,而且解压后占用内存也比JPG小得多。
综合来看,不应该使用JPG格式。
 

【转】JPG打包压缩后比原来尺寸还大的更多相关文章

  1. ASP.NET MVC 4 RC的JS/CSS打包压缩功能 (转载)

    ASP.NET MVC 4 RC的JS/CSS打包压缩功能 打包(Bundling)及压缩(Minification)指的是将多个js文件或css文件打包成单一文件并压缩的做法,如此可减少浏览器需下载 ...

  2. (转)ASP.NET MVC 4 RC的JS/CSS打包压缩功能

    转自:http://www.cnblogs.com/shanyou/archive/2012/06/22/2558580.html 打包(Bundling)及压缩(Minification)指的是将多 ...

  3. ASP.NET MVC 4 RC的JS/CSS打包压缩功能

    打包(Bundling)及压缩(Minification)指的是将多个js文件或css文件打包成单一文件并压缩的做法,如此可减少浏览器需下载多个文件案才能完成网页显示的延迟感,同时通过移除JS/CSS ...

  4. 在MVC中使用Bundle打包压缩js和css

    第一步:安装 安装“System.Web.Optimization”:在中“NuGet”中搜索 安装. 第二步:配置 配置“Views”目录下的“web.config”文件增加“System.Web. ...

  5. vue使用webpack压缩后体积过大要怎么优化

    vue使用webPack压缩后存储过大,怎么优化 在生产环境去除developtool选项 在webpack.config.js中设置的developtool选项,仅适用于开发环境,这样会造成打包成的 ...

  6. 【转】ASP.NET MVC 4 RC的JS/CSS打包压缩功能

    原文链接:http://www.cnblogs.com/shanyou/archive/2012/06/22/2558580.html 打包(Bundling)及压缩(Minification)指的是 ...

  7. webpack打包后不能调用,改用uglifyjs打包压缩

    背景: 项目基于原生js,没用到任何脚手架和框架,但也需要打包压缩. 项目的js中声明了一些全局变量 供其他js调用. 这时候如果用webpack打包,基于webpack特性,会嵌套一层大函数,会将j ...

  8. linux下如何打包压缩?解包解压?.tar文件.gz文件

    ===文件打包.压缩 ==打包 tar [root@521478.com]# tar -cvf etc1.tar /etc //c创建 v详细 f打包后文件名 [root@521478.com]# t ...

  9. Linux打包压缩.md

    Linux下打包压缩命令 下面学习一下压缩和打包的相关命令,首先得先明确两个概念,即:压缩和打包 .我们实际使用中一般是打包和压缩结合的使用,为了学习下面简要的介绍一下压缩文件或目录的命令. 压缩:将 ...

随机推荐

  1. URAL 1136 Parliament (DFS)

    题意 输入一棵树的后缀表达式(按左-右-中顺序访问),这棵树的每一个结点的数值都比它的左子树结点的数值大,而比它的右子树结点的数值小,要求输出其按右-左-中顺序访问的表达式.所有的数都为正整数,而且不 ...

  2. rabbitmq 对多服务器p2p模式配置的一个测试

    一直对rabbitmq p2p 模式的多服务器下做相同配置的 各个服务器数据接受情况比较好奇 今天有空测试了下 xml 文件 <?xml version="1.0" enco ...

  3. 剑指offer+名企面试官精讲典型编程题,28题扩展题

    body, table{font-family: 微软雅黑; font-size: 13.5pt} table{border-collapse: collapse; border: solid gra ...

  4. 线程的同步之Synchronized在单例模式中的应用

    synchronized在单例模式中的使用 在单例模式中有一种懒汉式的单例,就是类初始化的时候不创建对象.等第一次获取的时候再创建对象.这种单例在单线程下是没有问题的获取的也都是同一个对象.但是如果放 ...

  5. 《转》深入理解Activity启动流程(二)–Activity启动相关类的类图

    本文原创作者:Cloud Chou. 出处:本文链接 本系列博客将详细阐述Activity的启动流程,这些博客基于Cm 10.1源码研究. 在介绍Activity的详细启动流程之前,先为大家介绍Act ...

  6. OMAP4之DSP核(Tesla)软件开发学习(二)Linux内核驱动支持OMAP4 DSP核

    注:必须是Linux/arm 3.0以上内核才支持RPMSG,在此使用的是.config - Linux/arm 3.0.31 Kernel Configuration.(soure code fro ...

  7. 在.NET开发中的单元测试工具之——NUnit

    NUnit介绍 NUnit是一个专门针对于.NET来写的单元测试框架,它是xUnit体系中的一员,在xUnit体系中还有针对Java的JUnit和针对C++的CPPUnit,在开始的时候NUnit和x ...

  8. mac 终端 使用ftp命令

    Mac下使用命令行登陆ftp 最近使用forklift下载服务器pureftp上的东西,总是断断续续的,经常下载到99%然后显示下载失败,非常不舒服!原以为是forklift的问题,换了transmi ...

  9. 关于VC中LineDDA函数的调用

    在项目里碰到这个函数,不知道怎么使用,记录在这里. 该函数的原型如下: BOOL LineDDA(int nXStart, int nYStart, int nXEnd, int nYEnd, LIN ...

  10. 搭建开发环境(React Native)

    来源:http://reactnative.cn/docs/0.31/getting-started.html 在GitHub上修改这篇文档 欢迎使用React Native!这篇文档会帮助你搭建基本 ...