随着移动照相硬件的迅速发展,我们的手机捕捉和存储的文件越来越大。上传这些大文件会消耗移动数据;它们可能需要很长时间才能加载;有时,文件根本无法加载。为了使上传过程更加高效,我们开发了一个适用于 Android 和 iOS 的图像处理库Spectrum。借助 Spectrum,我们提高了应用中大规模图像上传的可靠性和质量。我们最近在droidcon SF大会上将 Spectrum 作为一个开源项目进行了展示,现在,我们在 GitHub 上正式发布Spectrum 1.0.0。
通向更好的移动图像生成之路
第一步在上传图像之前开始。通过转码减少文件大小,可以快速减少数据消耗,提高上传可靠性。这是一个简单的解决方案,但是,要在保证质量的同时减小尺寸需要深入理解各种处理步骤和图像格式。
使用平台提供的图像处理 API 是一种可能的解决方案。但是,大量的移动平台和不断发展的 API 会产生不同的输出。为了服务于广大开发人员,平台隐藏了我们为优化输出而希望控制的细节和参数。通常,常见任务(如 EXIF 元数据解释)会导致代码重复,进而妨碍维护和全局改进。使用最新的压缩库,如 MozJpeg,需要用 C/C++编写的原生代码。我们想让开发人员更容易发送较小的文件,同时保持对图像质量的控制,而不需要编写自定义的或难以维护的解决方案。
现代智能手机捕捉的图像分辨率很高,大文件使得某些移动网络上的上传不可靠。以全分辨率发送通常是一种浪费,因为内容传递网络(CDN)无论如何都会调整接收方的图像大小。
调整发送方设备上的图像大小可以减少发送图像所需的带宽,最小化整个管道的负载开销,改善端到端体验。剩下的挑战是如何在保持图像质量的同时受益于较小的文件大小。
Spectrum:构建图像处理基础设施
对于移动开发人员来说,Spectrum 使常见的图像操作变得简单、高效、一致。它的声明性 API 允许开发人员关注所需的输出属性,而不是单个步骤。其次,这使得 Spectrum 可以透明地选择最优的方式来满足转码请求。例如,如果有机会,Spectrum 会优先使用无损操作对JPEG图像进行裁剪和旋转。另一个例子是调整大小,Spectrum 会优化解码器采样和像素级完美调整(pixel-perfect resizing)之间的相互作用。
“菜谱(Recipes)”帮助开发人员为每个请求选择最佳的执行顺序。这些是由插件提供的。例如,JPEG 插件将提供 JPEG 图像无损裁剪和旋转菜谱。所有菜谱都在内部聚合并排序,这样,无损且高效的菜谱就位于顶部。对于每个请求,Spectrum 将迭代列表并执行第一个匹配(因此是最有效)的菜谱。最后一个方法是一个通用菜谱,它可以通过解码和编码图像来处理任何请求。
Spectrum 的内核是用 C++编写的,可以在 Android 和 iOS 应用之间共享,这使得我们的输出更加一致。它提供的Java和Objective-C API 只是对这个内核的简单包装,目的是简化开发。此外,C++内核提供了对内存分配的更多控制,通常会使计算密集型操作具有更高的执行速度。
与原生库(如MozJpeg)的集成使得 Spectrum 可以控制通用平台 API 之外的编码参数。它使得开发人员可以利用计算密集型编码,这需要更多的处理时间,但大大减少了文件大小。例如栅格量化和扫描优化。这在移动端是一个重要的权衡。在移动端,缓慢的网络连接会影响上传体验。它还使我们能够控制更高级的参数,如色度抽样,利用边缘锐化和插图提高图像质量。一致的 API 使得不是图像专家的开发人员也能够利用这些特性。
该库的内核是用 C++实现的。它将传入请求与一组可以实现图像操作的“菜谱”进行匹配。这里会优先考虑更高效的无损操作。插件提供了对图像格式和其他菜谱的支持。
我们希望 Spectrum 能像帮助 Facebook 实现更好的图像生成体验一样,让开发者受益。在我们的应用中,Spectrum 提高了整个应用程序大规模图像上传的可靠性和质量。与基线编码器相比,与 Mozilla JPEG 的默认集成使得上传文件的大小减少了 15%。我们很希望看到社区如何使用Spectrum 1.0.0库来改善应用程序的照片体验。
查看英文原文:Facebook open-sources Spectrum 1.0.0 for better mobile image production
评论