为什么Android的图片质量没有iOS的高?

经常看到有人问:“安卓版微信发出去的图片怎么那么渣!比iPhone的差远了!”。不只是微信,很多应用安卓版的图片质量就是要比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进行了良好的封装,基于这个引擎可以很方便为操作系统、浏览器等开发图像处理功能。

ibjpeg在压缩图像时,有一个参数叫optimize_coding,关于这个参数,libjpeg.doc有如下解释:

boolean optimize_coding
TRUE causes the compressor to compute optimal Huffman coding tables
for the image. This requires an extra pass over the data and
therefore costs a good deal of space and time. The default is
FALSE, which tells the compressor to use the supplied or default
Huffman tables. In most cases optimal tables save only a few percent
of file size compared to the default tables. Note that when this is
TRUE, you need not supply Huffman tables at all, and any you do
supply will be overwritten.

这段话大概的意思就是如果设置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还有性能上的好处,这里就不再赘述了)

最后,附上我们团队在github上的开源项目地址,供参考:https://github.com/bither


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 如果你在使用 uniapp 在 iOS 上传图片时遇到了失败的情况,那么可能是因为以下几种原因造成的: 1. 你的网络环境不稳定,导致上传失败。 2. 你的图片太大,超过了服务器能够处理的大小限制。 3. 服务器端出了问题,导致无法正常接收上传的图片。 4. 你的 uniapp 客户端代码存在 bug,导致无法正常上传图片。 如果你不确定是哪个原因造成的上传失败,建议你尝试以下步骤来解决这个问题: 1. 确保你的网络环境良好。 2. 尝试将图片的大小压缩到合理的范围内再上传。 3. 尝试在不同的时间上传图片,如果总是在同一时间上传失败,可能是服务器端出了问题。 4. 检查你的 uniapp 客户端代码,确保没有任何 bug 影响了图片上传的过程。 ### 回答2: uniapp 是一种基于Vue.js开发的跨平台应用开发框架,支持同时开发iOSAndroid应用。对于uniapp在iOS上上传图片失败的问题,可能有以下几个原因: 1. 权限问题:iOS系统对于相机和相册的访问需要获取用户的权限,如果应用未获取相应的权限,就无法上传图片。可以在uniapp的manifest.json文件中设置相应的权限配置。 2. 图片路径问题:iOS系统中,相机拍摄的照片和从相册选取的照片存储在不同的位置,导致图片路径可能不一致。在uniapp中,可以使用uni.chooseImage方法选择照片,回调函数中可以获取到选择的图片的临时文件路径,可以根据具体的需要进行处理。 3. 图片大小限制:iOS系统对于图片大小有一定的限制,如果选择的图片大小超过了系统限制,上传可能会失败。可以在uniapp中使用uni.compressImage方法对图片进行压缩,减小图片的大小。 4. 上传服务器问题:上传图片失败也有可能是服务器端的问题,可能是上传接口的问题或者网络连接的问题。可以使用浏览器调试工具或者抓包工具查看具体的错误信息,以便排查问题。 针对以上可能的问题,可以逐一排查并解决。同时,要确保uniapp使用的是最新版本,以获得最新的修复和功能支持。如果以上方法都没有解决问题,可以参考uniapp官方文档或者查找相关的社区讨论,寻求帮助。 ### 回答3: uniapp 是一种跨平台开发框架,它可以将同一个代码基础同时编译成多个平台的应用程序。但是在 iOS 平台上,有时候会出现上传图片失败的情况。 这种问题的出现可能有多种原因,我们可以尝试以下几个解决方法: 1. 检查网络连接:首先,我们需要确保 iOS 设备连接到了稳定的网络,如果网络不稳定或者信号弱,可能会导致上传失败。可以尝试连接到其他网络或者重启网络设备来解决问题。 2. 检查文件格式:iOS 平台对文件格式有一些限制,如果上传的图片格式不被支持,可能会导致上传失败。可以将图片转换成 iOS 支持的格式,例如 JPEG 或者 PNG 格式,然后尝试重新上传。 3. 检查文件大小:iOS 平台对上传文件的大小也有一定限制,如果上传的图片文件过大,可能会导致上传失败。可以尝试缩小图片的尺寸或者压缩图片质量,然后重新上传。 4. 检查权限设置:iOS 平台对应用的文件访问权限有一些限制,如果没有正确设置权限,可能会导致上传失败。可以在应用的设置中检查并修改文件访问权限,然后重新上传。 如果以上方法都没有解决问题,可以尝试查看 iOS 设备的日志或者调试信息,看是否有相关的错误提示。另外,也可以尝试在其他 iOS 设备上运行同样的代码,以确定是否是设备特定的问题。如果问题仍然存在,可以提供更多的细节信息,以便我们能够更好地帮助解决该问题。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值