为什么微信android图片质量会比iphone的差?
为什么微信android图片质量会比iphone的差?
我们团队最初也纠结过这个问题,费了半天劲、绕了好大圈,直到最后才发现,原来这是谷歌犯得一个“小”错误,而且一直错到了今天。
谷歌的错就在于:libjpeg。
libjpeg是广泛使用的开源JPEG图像库(参考 http://en.wikipedia.org/wiki/Libjpeg ),安卓也依赖libjpeg来压缩图片。通过查看源码,我们会发现安卓并不是直接封装的libjpeg,而是基于了另一个叫Skia的开源项目(http://en.wikipedia.org/wiki/Skia_Graphics_Engine)来作为的图像处理引擎。Skia是谷歌自己维护着的一个大而全的引擎,各种图像处理功能均在其中予以实现,并且广泛的应用于谷歌自己和其它公司的产品中(如:Chrome、Firefox、Android等)。Skia对libjpeg进行了良好的封装,基于这个引擎可以很方便为操作系统、浏览器等开发图像处理功能。
libjpeg在压缩图像时,有一个参数叫optimize_coding,关于这个参数,libjpeg.doc有如下解释:

这段话大概的意思就是如果设置optimize_coding为TRUE,将会使得压缩图像过程中基于图像数据计算哈弗曼表(关于图片压缩中的哈弗曼表,请自行查阅相关资料),由于这个计算会显著消耗空间和时间,默认值被设置为FALSE。
这段解释乍看起来没有任何问题,libjpeg的代码也经受了十多年的考验,健壮而高效。但很多人忽略了这一点,那就是,这段解释是十多年前写的,对于当时的计算设备来说,空间和时间的消耗可能是显著的,但到今天,这似乎不应再是问题,相反,我们应该更多的考虑图片的品质(越来越好的显示技术)和图片的大小(越来越依赖于云服务)。
谷歌的Skia项目工程师们最终没有设置这个参数,optimize_coding在Skia中默认的等于了FALSE,这就意味着更差的图片质量和更大的图片文件,而压缩图片过程中所耗费的时间和空间其实反而是可以忽略不计的。那么,这个参数的影响究竟会有多大呢?
经我们实测,使用相同的原始图片,分别设置optimize_coding=TRUE和FALSE进行压缩,想达到接近的图片质量(用Photoshop放大到像素级逐块对比),FALSE时的图片大小大约是TRUE时的5-10倍。换句话说,如果我们想在FALSE和TRUE时压缩成相同大小的JPEG图片,FALSE的品质将大大逊色于TRUE的(虽然品质很难量化,但我们不妨说成是差5-10倍)。
我们又对Android和iOS进行了对比(均使用标准的JPEG压缩方法),两个系统都没有提供设置optimize_coding的接口(通过阅读源码,我们已经知道Android是FALSE,iOS不详),当压缩相同的原始图片时,结果也是一样,iOS完胜。想要品质接近,文件大小就会差出5-10倍,而如果要压缩出相同大小的文件,Android的压缩品质简直就是惨不忍睹。
结果说明,苹果很清楚optimize_coding参数和哈弗曼表的意义,这里需要特别指出,苹果使用的哈弗曼表算法与libjpeg(及我们后来自行采用的libjpeg-turbo)不同,像素级可以看出区别,苹果似乎基于libjpeg又进行了进一步的优化,压缩出来的图片细节上更柔和、更平滑。
以上试验,我们尝试过多个原图、多种压缩比例,试验结果均类似,如有兴趣,您不妨也自行进行尝试。
最终我们决定,不再使用安卓系统原生的JPEG压缩方法,而是基于libjpeg-turbo自行编译了一版native的安卓库,专门用来压缩图片,这样在我们的产品中,就做到了仅仅用1/5的图片大小,就能让用户得到不逊色甚至更优的图片品质,对于我们团队来说,费了半天劲、绕了好大圈是非常值得的。(使用libjpeg-turbo还有性能上的好处,这里就不再赘述了)
转载自:http://www.jb51.net/shouji/211369.html
为什么微信android图片质量会比iphone的差?的更多相关文章
- 为什么Android的图片质量会比iPhone的差?
经常看到有人问:“安卓版微信发出去的图片怎么那么渣!比iPhone的差远了!”.不只是微信,很多应用安卓版的图片质量就是要比iPhone版逊色很多,这到底是怎么回事? 我们团队最初也纠结 ...
- 通过微信Android和iOS版,看两大系统的差异
由于设计师或者产品经理使用的移动设备大部分是iPhone,所以在做设计时,容易忽略Android和iOS的差异,按照自己的使用习惯进行设计,导致大部分设计师或产品经理做出的设计都是基于iOS规范或习惯 ...
- 微信Android客户端架构演进之路
这是一个典型的Android应用在从小到大的成长过程中的“踩坑”与“填坑”的历史.互联网的变化速度如此之快,1年的时间里,可以发生翻天覆地的变化.今天在这里,重新和大家回顾微信客户端架构的演进过程,以 ...
- 转:微信Android客户端架构演进之路
转自: http://www.infoq.com/cn/articles/wechat-android-app-architecture 微信Android客户端架构演进之路 作者 赵原 发布于 20 ...
- 微信android混淆打包减少安装包大小
首先,感谢微信android团队的分享 微信中的资源混淆工具主要为了混淆资源ID长度(例如将res/drawable/welcome.png混淆为r/s/a.png),同时利用7z深度压缩,大大减少了 ...
- 凡信(超仿微信Android版)开源了,内有源码下载 -
韩梦飞沙 韩亚飞 313134555@qq.com yue31313 han_meng_fei_sha 凡信(超仿微信Android版)开源了,内有源码下载 - IM Geek开发者社区-移动 ...
- 微信android手机中点击大图片会自动放大图片
自己使用的是微信Android客户端,使用img标签的src属性将图片设置好了以后,在微信中调试,点击图片竟然放大,自己没写放大图片的方法,也没有调用wx.previewImage()方法,最后查找, ...
- 微信小程序中的iPhone X适配问题
微信小程序中的iPhone X适配问题 小程序中下方的导航会被iPhone X下面的那条黑线盖住[微笑脸],所以要专门为了iPhone X做样式上的适配[微笑脸] wx.getSystemInfo({ ...
- 微信Android终端SDK新手使用指南
1.申请你的AppID 请到 开发者应用登记页面 进行登记,登记并选择移动应用进行设置后,将获得AppID,可立即用于开发.但应用登记完成后还需要提交审核,只有审核通过的应用才能正式发布使用. 2.下 ...
随机推荐
- 20130625修改hbase的hbase-env导致导出器导出数据的速度变慢
将hbase的 export HBASE_OPTS="-ea -XX:+UseConcMarkSweepGC -XX:+CMSIncrementalMode" 改为 export ...
- Qt搭建多线程Server
起因是MySQL在Android上没有驱动.也就是说,移动端想要访问远程数据库,必须通过一台(或多台)PC进行中转. 中转PC作为Server,接受来自移动端Socket访问数据库的要求,Server ...
- bzoj2962 序列操作 题解
题目大意: 有一个长度为n的序列,有三个操作1.I a b c表示将[a,b]这一段区间的元素集体增加c,2.R a b表示将[a,b]区间内所有元素变成相反数,3.Q a b c表示询问[a,b]这 ...
- ACM 字符串替换
字符串替换 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 编写一个程序实现将字符串中的所有"you"替换成"we" 输入 ...
- ACM Minimum Inversion Number 解题报告 -线段树
C - Minimum Inversion Number Time Limit:1000MS Memory Limit:32768KB 64bit IO Format:%I64d &a ...
- [Cocos2D-x For WP8]Label标签
Label标签主要会用于在游戏中显示一些文字字符串类型的信息.那么在Cocos2D-x里面主要会有下面的一些创建标签的方式: 1.使用CCLabelTTF类生成系统文字的标签,编程语法如下: CCLa ...
- 【BZOJ】2212: [Poi2011]Tree Rotations
题意 给一棵\(n(1 \le n \le 200000)\)个叶子的二叉树,可以交换每个点的左右子树,要求前序遍历叶子的逆序对最少. 分析 可以发现如果交换非叶结点的左右子树,对子树内的交换无影响, ...
- 【BZOJ】3621: 我想那还真是令人高兴啊
http://www.lydsy.com/JudgeOnline/problem.php?id=3621 题意:给两个三角形,问A能否通过旋转伸缩到B. #include <bits/stdc+ ...
- JavaScript进阶(二)
什么是事件 JavaScript 创建动态页面.事件是可以被 JavaScript 侦测到的行为. 网页中的每个元素都可以产生某些可以触发 JavaScript 函数或程序的事件. 比如说,当用户单击 ...
- NOI模拟赛Day5
T1 有and,xor,or三种操作,每个人手中一个数,求和左边进行某一种运算的最大值,当t==2时,还需要求最大值的个数. test1 20% n<=1000 O(n^2)暴力 test2 2 ...