作者:刘源
链接: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. js 数据函数

    //shift:删除原数组第一项,并返回删除元素的值:如果数组为空则返回undefined var a = [1,2,3,4,5]; var b = a.shift(); //a:[2,3,4,5]  ...

  2. jquery检测input checked 控件是否被选中的方法

    jquery检测input checked 控件是否被选中 js部分 复制代码代码如下: function tongyianniu(){ var gouxuan=$('input[type=check ...

  3. Alpha发布

    作业链接[https://edu.cnblogs.com/campus/nenu/2018fall/homework/2283] 视频展示 链接[https://v.youku.com/v_show/ ...

  4. 安卓开发分享功能,分享到facebook网页上不显示图片的问题

    最近公司要上分享功能,分享的地方包括微信,qq,facebook,功能完成后,发现分享到facebook的内容只有文字可以显示,图片不显示,其中图片存储是使用七牛的服务器:而分享到微信和qq都可以正常 ...

  5. react native 获取 软键盘高度 和 新增软键盘的组件

    import React, { Component } from 'react'; import { AppRegistry, StyleSheet, Text, View, Keyboard, Te ...

  6. pandas 之 concat

    本文摘自:http://pandas.pydata.org/pandas-docs/stable/merging.html 前提: ide: liuqian@ubuntu:~$ ipython 准备: ...

  7. Redis学习笔记-常用命令篇(Centos7)

    redis提供了丰富的命令,这些命令可以在linux终端使用.在各类语言中,这些命令都有对应的方法. 一.键值相关 1.keys 返回满足给定pattern的所有key 127.0.0.1:6379& ...

  8. python try except, 异常处理

    http://www.runoob.com/python/python-exceptions.html http://blog.sciencenet.cn/blog-3031432-1059523.h ...

  9. python pandas.DataFrame .loc,.iloc,.ix 用法

    refer to: http://www.cnblogs.com/harvey888/p/6006200.html

  10. 设计模式(Python)-观察者模式

    本系列文章是希望将软件项目中最常见的设计模式用通俗易懂的语言来讲解清楚,并通过Python来实现,每个设计模式都是围绕如下三个问题: 为什么?即为什么要使用这个设计模式,在使用这个模式之前存在什么样的 ...