实战中学习:程序员要了解的图片知识

韩宇斌,现就职于罗辑思维得到后端,曾效力于好大夫在线、云智慧等。一线负责过传统软件公司ToB类和互联网公司ToC类的业务系统,理解体会过其中的相同与不同,擅长利用DDD和OO思想对业务需求进行分析建模与设计开发,曾发表《DDD 战略建模在重构业务系统时的实践》。

文章正文

问题背景和应急方案

某个刚刚完成开发的产品进入线上内测环节,暴露出来了两个较为严重的问题:

  1. iOS 客户端偶尔会崩溃。
  2. 客户端列表打开缓慢,影响体验。

为什么是偶现呢?为什么在测试环境没有发生这样的情况呢?

经过各开发端简单的调查后,定位到的原因是和图片有关,只要服务端列表接口返回的数据中包括了高清大图的 URI,就会导致上面这两个问题的出现。线上环境的内容文稿中需要正式的配图,运营同学从素材库中精选了 10M~30M 的高清大图直接上传使用,而我们的图片上传环节还没有来得及做针对高清大图的压缩优化……

原因分析

  • 客户端崩溃:客户端拿到图片要在端上做处理后放到控件上显示,控件尺寸是 720*300,需要按产品规则来适配和裁剪(例如四个角处理为圆弧的)。对 33M 的图片进行缩放适配和裁剪时,ios 客户端要去申请占用约 200M 的内存,如果申请不到足够的内存,就会频繁 io 导致卡顿甚至崩溃。
  • 列表打开缓慢:图片越大,下载耗时造成延迟的可能性也就越大。即使按照 1 秒钟 1-5M 的下载速度,单张 33M 的图片也需要 5~30 秒。列表要请求 20 张这样的图片,使用并行方式来请求并渲染,也依然耗时较多,更何况,下载速度达到 5M 的时候是不多的,我们几乎能想象得到图片展示的缓慢程度。

于是,图片大小和格式,这个没有被认为是个问题的 X 因素,需要我们来重视起来。

应急方案

运营应该在上传图片前对图片进行处理和压缩吗?技术人员一致认为这是应该的,运营要对自己要上传使用的图片“负责”,而产品经理和运营都表示反对,他们之所以不接受全部图片由运营处理后再上传,有以下原因:

  • 工作重心不在图片处理上。该产品相对于别的产品,日均内容生产的工作量较大,运营全部处理图片,会带来较高的时间成本和学习成本。
  • 内容的生产后台,合作的老师也会用,没法直接要求老师。

经过和运营、产品经理的协商,他们同意了在整改方案上线以前,先手动压缩处理图库的高清图片,把大小控制在 500k 以内,然后再上传作为内容素材。

紧急方案只是一个过渡,自动压缩处理图片,以及图片在各个端上的展示,都需要我们去找一个合适的方案。

为什么要对图片进行处理优化

出现了页面加载慢或者 App 卡顿现象,谁来接这个锅?

  • 前端和客户端?对于大多数前端工程师来说,图片就是 UI 设计师(或者自己)切好的图,要做的只是把图片丢进项目中,然后用“炫酷”的方式呈现在页面上,而且他们也经常把精力放在如何优化复杂的交互逻辑,项目的打包优化构建,如何分包,如何抽取第三方库........
  • 服务端?对于大多数的服务端开发工程师来说,图片更不是我们关心的事情,甚至也不会纳入我们的知识体系中,给我们个图片 URI 的地址,我们保存起来,需要的时候吐给前端或客户端,他们自己玩去,说到性能优化我们更应该关注 cpu、内存、算法等……

谁都有足够的理由来甩锅,但是问题还是需要去解决的,本文就介绍一些作为服务端开发,也要了解些图片的知识。

图片曾经的地位

进入到了移动互联网时代后,App 占据一个企业的主要流量,使得我们忘记了,图片曾经是一个网站最大头的那块加载资源,一度占到整个互联网 62% 的流量(数据来自 HTTP Archieve)。

图片占比

对图片进行处理优化的获益点

提升用户体验

高达 10~30M 的高清大图,无论是运营人员上传还是用户下载,都会带来 10 秒甚至更久的等待,这对用户体验是极大的伤害。如果对图片进行压缩,比如压缩至 500kb,即使用户平均网速为 500k/s,所需时间将缩短为 1 秒,而 app 端也可以减少耗费不必要的资源去处理图片的显示,运行将更流畅,可以显著提高用户体验。

降低流量耗费

高达 10~30M 的高清大图,用户浏览 10 个内容,就相当于在视频 app 在线观看一部 120 分钟标清格式的电影了,这个流量耗费程度是我们不能接受的。如果用移动运营商的流量,1 个 G 的包月看不了几篇就给用完了,不能忍啊,估计会骂街的。

降低存储所用空间

一张原始图像(1920x1080),如果每个像素 32bit 表示(RGBA),那么,图像需要的内存大小 1920x1080x4 = 8294400 Byte,大约 8M,如果这样,1G 硬盘才存 100 多张图片!无论是上传到图片存储服务器的成本,还是用户终端本地空间的占用,都是超出预期的。

注:RGBA 是代表 Red(红色)Green(绿色)Blue(蓝色)和 Alpha 的色彩空间。

这几个获益点,值得我们花些时间去了解一下图片处理的相关知识。

作者正在撰写中...
隐藏内容 支付可见
内容互动
写评论
加载更多
评论文章
¥1 购买
× 订阅 Java 精选频道
¥ 元/月
订阅即可免费阅读所有精选内容