济南IT培训 > 达内新闻
为提高用户体验,Yelp 是如何无损压缩图片的
- 发布:济南IT培训
- 来源:济南IT培训
- 时间:2017-09-23 14:01
Yelp 拥有超过 1 亿张由用户生成的照片,这些照片从晚餐、理发,到我们最新的功能之一:yelfies.这些图像占据了用户 APP 和网站的大部分带宽,这意味着存储和传输的巨大成本.为了向用户提供最好的体验,我们努力优化这些图片并将其平均大小缩小了 30%.这样节省了用户的时间和带宽,并降低了为这些图像提供服务的成本.哦,我们这样做都没有降低图像的质量呢!
济南IT培训课程结合行业技术趋势及企业用人需求的变化,及时更新,课程至少每半年进行一次升级,保证学习质量.
背景
Yelp 已经帮用户存储上传的照片超过 12 年了.我们那些将无损格式的图片(PNG,GIF)保存成 PNG 格式,而所有其他的格式的图片则保存成 JPEG 格式.我们保存图片用的是 Python 和 Pillow,并使用如下代码片段,开启了我们照片上传的故事:
# do a typical thumbnail, preserving aspect ratio
new_photo = photo.copy()
new_photo.thumbnail(
(width, height),
resample=PIL.Image.ANTIALIAS,
)
thumbfile = cStringIO.StringIO()
save_args = {'format': format}
if format == 'JPEG':
save_args['quality'] = 85
new_photo.save(thumbfile, **save_args)
以此作为起点,我们开始研究潜在的文件大小优化方法,可以让我们在不损失质量的前提下使用.
优化
首先,我们不得不决定是自己来处理这个问题,还是让 CDN 提供商用他们的魔力来神奇地改变我们的照片.在优先保证高质量的内容前提下,去评估众多选项并使得潜在的尺寸与质量相互抵消是有意义的.我们先行调查了当前照片文件大小缩小的现状 – 可以做出什么改变,以及与每个改变相关联的大小/质量下降.随着这项调查的完成,我们决定从三大类方法来着手.这篇文章剩下的部分解释了我们做了什么,并在每项优化中获得了多少收益.
1.Pillow中的改变
优化标志
渐进的JPEG
2.应用照片逻辑的更改
大型 PNG 格式图的检测
动态 JPEG 质量
3.JPEG编码器更改
Mozjpeg(网格量化,自定义量化矩阵)
Pillow 中的改变
济南IT培训课程结合行业技术趋势及企业用人需求的变化,及时更新,课程至少每半年进行一次升级,保证学习质量.
标志位优化
这是我们最简单的更改之一:启用 Pillow 中的设置,以 CPU 耗时为代价(optimize = True)来节约更多的文件大小. 由于该权衡的本质,这样做并不会影响图像质量.
济南IT培训课程结合行业技术趋势及企业用人需求的变化,及时更新,课程至少每半年进行一次升级,保证学习质量.
对于 JPEG 格式的图片,该标志位会指示编码器,通过扫描每张图片做一次附加的遍历,来找到最佳霍夫曼编码.对每张图片的第一遍扫描,我们不是写入文件,而是计算每个值的出现统计,这是计算理想编码所需要信息.PNG 内部使用 zlib,因此在这种情况下,标志位优化能有效地指示编码器使用 gzip -9,而不是 gzip -6.
这是一项简单的改进,但事实证明它并非灵丹妙药,只减少百分之几的文件大小.
渐进式 JPEG
将图像保存为 JPEG 格式时,你可以选择几种不同的类型:
从上到下加载的 JPEG 标准图像.
渐进式 JPEG 图像,从较模糊加载到较不模糊.Pillow(progressive = True)可以轻松地启用渐进式选项. 因而,人类肉眼可感知到性能有了提升(也就是说,当图像部分缺失时,更容易注意到它不是完全锐利的).
此外,渐进式文件打包方式通常会使得文件尺寸减少.如维基百科文章中所详尽解释的那样,JPEG 格式在 8×8 像素块上使用 Z 字形模式进行熵编码.当这些像素块的值被解包并按顺序排列时,我们通常首先得到的是非零数字,然后是 0 的序列,用该模式对于图像中的每个 8×8 块进行重复和交织.在使用渐进编码时,解开的像素块的顺序发生了改变.每个块值较高的数字会首先出现文件中(它给出了渐进式图像最早扫描到的不同阻塞),并且那些能增加出色细节的小数字(包括更多的 0),它们的跨度将更长,并一直持续到末位.图像数据的这种重新排序不会改变图像本身,而是增加了在一行中的可能存在的 0 的数量(这样可以更容易地压缩).
应用照片逻辑的改变
大型 PNG 格式图片的检测
Yelp 为用户生成的内容提供了两种图像格式 – JPEG 和 PNG.JPEG 是一种很好的照片格式,但通常会与高对比度设计内容(如 logo)相结合.相比之下,PNG 是完全无损的,非常适合图形,但对于那些小失真不可见的照片来说占用的空间太大了.在用户上传实际照片是 PNG 格式的情况下,我们识别这些文件并将其另存为 JPEG 格式,可节省下大量的存储空间.Yelp 上一些常见的 PNG 照片来源于移动设备由和应用程序拍摄的截图,这些照片是通过添加特效或边框修饰了的.
(左)一个典型的具有 logo 和边框的复合 PNG 格式的上传图. (右)一个典型的来自于屏幕截图的 PNG 格式的上传图.
我们想减少这些不必要的 PNG 格式的图片数量,但重要的是要避免矫枉过正或降低了 logo 和图形等的质量.我们应该如何区分出一张图片中属于照片的部分呢?从像素层面可以做到吗?
使用了 2500 张图片作为实验样本后,我们发现文件大小和独特像素的结合可以很好地区分照片.我们用我们最大的分辨率生成候选缩略图,看看输出PNG文件是否大于 300 KiB.如果是,我们还将检查图像内容,查看是否有超过 2^16 种独特颜色(Yelp 将 RGBA 格式的上传图片转成 RGB 格式,但如果没这样做的话,我们也会检查).
在实验数据集中,那些手动调整阈值来定义成" bigness "占了有可能缩小的文件大小的 88%(即如果我们要转换所有图像,我们预期的文件大小的缩小),这是在不会导致转换后图形的任何假阳性的前提下进行的.
动态的 JPEG 质量
缩小 JPEG 文件大小的第一个也是最为人所知的一种方式是称为质量的设置.许多能保存 JPEG 格式图片的应用程序会将质量指定为一个数字.
质量这个词有点抽象.事实上,一幅 JPEG 格式的图像的每个颜色通道都有单独的质量.质量等级从 0 到 100 映射到颜色通道的不同量化表,取决于丢失了多少数据(通常是高频成分).信号域中的量化是 JPEG 编码过程中丢失信息的步骤之一.
减小文件大小的最简单的方法是降低图像的质量,这会引入更多的噪声.不是每张图片在一个给定的相同质量水平上都会丢失相同的信息量.
我们可以为每张图片动态地选择一种质量优化设置,找到质量和存储大小之间的理想平衡.有两种方法可以做到这一点:
自下而上:这些是通过处理 8 x 8 像素块级别的图像生成调谐量化表的算法.它们计算出丢失了多少理论上的质量,以及丢失的数据如何放大或消除,对人眼可见失真的多或少.
自上而下的:这些算法是将整张图片与其原始无失真版本进行比较,检测丢失了多少信息.通过迭代生成具有不同质量设置的候选图像,我们可以选择其中一张图片,作为满足某种评估算法的最低评估水平的图像.
我们评估了一种自下而上的算法,在实验中,在我们希望使用的质量范围的上限内没有产生合适的结果(尽管它似乎仍然具有中档图像质量的潜力, 这时编码器可以开始更冒险地去丢弃它的字节).关于这一策略的众多学术论文在90年代初就有发表,该方法对计算能力要求很高,并且走了选项 B 地址这类的捷径,例如不评估块之间的交互.
所以我们采取了第二种方法:使用对分的算法生成不同质量水平的候选图像,并通过使用 pyssim 函数来计算其结构相似性度量(SSIM),来评估每个候选图像的质量下降,直到该值处于可配置但阈值也还处于静态.这允许我们选择性地降低文件的平均大小(和平均质量),仅仅针对那些已经开始产生肉眼可识别的质量下降的图像.
在下图中,我们绘制了用3种不同质量方法生成的 2500 张图像的SSIM值的表.
1、用一种质量为 85 的初始方法作出原始图像,使用蓝线来绘制.
2、一种能降低文件大小,质量改为 80 的替代方法,用红线来绘制.
3、我们在最后选用了一种方法,使用橙色绘制动态质量的 SSIM 为 80 – 85 的图,即选择质量为 80 到 85(含)的图像,这是基于一种满足或超过的 SSIM 比率:该比率是预先计算的、使转换发生在图像范围中间的某个静态值.这样我们可以降低文件的平均大小,而不会降低那些质量最差的图片的质量.
济南IT培训课程结合行业技术趋势及企业用人需求的变化,及时更新,课程至少每半年进行一次升级,保证学习质量.
最新开班时间
- 北京
- 上海
- 广州
- 深圳
- 南京
- 成都
- 武汉
- 西安
- 青岛
- 天津
- 杭州
- 重庆
- 哈尔滨
- 济南
- 沈阳
- 合肥
- 郑州
- 长春
- 苏州
- 长沙
- 昆明
- 太原
- 无锡
- 石家庄
- 南宁
- 佛山
- 珠海
- 宁波
- 保定
- 呼和浩特
- 洛阳
- 烟台
- 运城
- 潍坊
为提高用户体验,Yelp 是如何无损压缩图片的
- 发布:济南IT培训
- 来源:济南IT培训
- 时间:2017-09-23 14:01
Yelp 拥有超过 1 亿张由用户生成的照片,这些照片从晚餐、理发,到我们最新的功能之一:yelfies.这些图像占据了用户 APP 和网站的大部分带宽,这意味着存储和传输的巨大成本.为了向用户提供最好的体验,我们努力优化这些图片并将其平均大小缩小了 30%.这样节省了用户的时间和带宽,并降低了为这些图像提供服务的成本.哦,我们这样做都没有降低图像的质量呢!
济南IT培训课程结合行业技术趋势及企业用人需求的变化,及时更新,课程至少每半年进行一次升级,保证学习质量.
背景
Yelp 已经帮用户存储上传的照片超过 12 年了.我们那些将无损格式的图片(PNG,GIF)保存成 PNG 格式,而所有其他的格式的图片则保存成 JPEG 格式.我们保存图片用的是 Python 和 Pillow,并使用如下代码片段,开启了我们照片上传的故事:
# do a typical thumbnail, preserving aspect ratio
new_photo = photo.copy()
new_photo.thumbnail(
(width, height),
resample=PIL.Image.ANTIALIAS,
)
thumbfile = cStringIO.StringIO()
save_args = {'format': format}
if format == 'JPEG':
save_args['quality'] = 85
new_photo.save(thumbfile, **save_args)
以此作为起点,我们开始研究潜在的文件大小优化方法,可以让我们在不损失质量的前提下使用.
优化
首先,我们不得不决定是自己来处理这个问题,还是让 CDN 提供商用他们的魔力来神奇地改变我们的照片.在优先保证高质量的内容前提下,去评估众多选项并使得潜在的尺寸与质量相互抵消是有意义的.我们先行调查了当前照片文件大小缩小的现状 – 可以做出什么改变,以及与每个改变相关联的大小/质量下降.随着这项调查的完成,我们决定从三大类方法来着手.这篇文章剩下的部分解释了我们做了什么,并在每项优化中获得了多少收益.
1.Pillow中的改变
优化标志
渐进的JPEG
2.应用照片逻辑的更改
大型 PNG 格式图的检测
动态 JPEG 质量
3.JPEG编码器更改
Mozjpeg(网格量化,自定义量化矩阵)
Pillow 中的改变
济南IT培训课程结合行业技术趋势及企业用人需求的变化,及时更新,课程至少每半年进行一次升级,保证学习质量.
标志位优化
这是我们最简单的更改之一:启用 Pillow 中的设置,以 CPU 耗时为代价(optimize = True)来节约更多的文件大小. 由于该权衡的本质,这样做并不会影响图像质量.
济南IT培训课程结合行业技术趋势及企业用人需求的变化,及时更新,课程至少每半年进行一次升级,保证学习质量.
对于 JPEG 格式的图片,该标志位会指示编码器,通过扫描每张图片做一次附加的遍历,来找到最佳霍夫曼编码.对每张图片的第一遍扫描,我们不是写入文件,而是计算每个值的出现统计,这是计算理想编码所需要信息.PNG 内部使用 zlib,因此在这种情况下,标志位优化能有效地指示编码器使用 gzip -9,而不是 gzip -6.
这是一项简单的改进,但事实证明它并非灵丹妙药,只减少百分之几的文件大小.
渐进式 JPEG
将图像保存为 JPEG 格式时,你可以选择几种不同的类型:
从上到下加载的 JPEG 标准图像.
渐进式 JPEG 图像,从较模糊加载到较不模糊.Pillow(progressive = True)可以轻松地启用渐进式选项. 因而,人类肉眼可感知到性能有了提升(也就是说,当图像部分缺失时,更容易注意到它不是完全锐利的).
此外,渐进式文件打包方式通常会使得文件尺寸减少.如维基百科文章中所详尽解释的那样,JPEG 格式在 8×8 像素块上使用 Z 字形模式进行熵编码.当这些像素块的值被解包并按顺序排列时,我们通常首先得到的是非零数字,然后是 0 的序列,用该模式对于图像中的每个 8×8 块进行重复和交织.在使用渐进编码时,解开的像素块的顺序发生了改变.每个块值较高的数字会首先出现文件中(它给出了渐进式图像最早扫描到的不同阻塞),并且那些能增加出色细节的小数字(包括更多的 0),它们的跨度将更长,并一直持续到末位.图像数据的这种重新排序不会改变图像本身,而是增加了在一行中的可能存在的 0 的数量(这样可以更容易地压缩).
应用照片逻辑的改变
大型 PNG 格式图片的检测
Yelp 为用户生成的内容提供了两种图像格式 – JPEG 和 PNG.JPEG 是一种很好的照片格式,但通常会与高对比度设计内容(如 logo)相结合.相比之下,PNG 是完全无损的,非常适合图形,但对于那些小失真不可见的照片来说占用的空间太大了.在用户上传实际照片是 PNG 格式的情况下,我们识别这些文件并将其另存为 JPEG 格式,可节省下大量的存储空间.Yelp 上一些常见的 PNG 照片来源于移动设备由和应用程序拍摄的截图,这些照片是通过添加特效或边框修饰了的.
(左)一个典型的具有 logo 和边框的复合 PNG 格式的上传图. (右)一个典型的来自于屏幕截图的 PNG 格式的上传图.
我们想减少这些不必要的 PNG 格式的图片数量,但重要的是要避免矫枉过正或降低了 logo 和图形等的质量.我们应该如何区分出一张图片中属于照片的部分呢?从像素层面可以做到吗?
使用了 2500 张图片作为实验样本后,我们发现文件大小和独特像素的结合可以很好地区分照片.我们用我们最大的分辨率生成候选缩略图,看看输出PNG文件是否大于 300 KiB.如果是,我们还将检查图像内容,查看是否有超过 2^16 种独特颜色(Yelp 将 RGBA 格式的上传图片转成 RGB 格式,但如果没这样做的话,我们也会检查).
在实验数据集中,那些手动调整阈值来定义成" bigness "占了有可能缩小的文件大小的 88%(即如果我们要转换所有图像,我们预期的文件大小的缩小),这是在不会导致转换后图形的任何假阳性的前提下进行的.
动态的 JPEG 质量
缩小 JPEG 文件大小的第一个也是最为人所知的一种方式是称为质量的设置.许多能保存 JPEG 格式图片的应用程序会将质量指定为一个数字.
质量这个词有点抽象.事实上,一幅 JPEG 格式的图像的每个颜色通道都有单独的质量.质量等级从 0 到 100 映射到颜色通道的不同量化表,取决于丢失了多少数据(通常是高频成分).信号域中的量化是 JPEG 编码过程中丢失信息的步骤之一.
减小文件大小的最简单的方法是降低图像的质量,这会引入更多的噪声.不是每张图片在一个给定的相同质量水平上都会丢失相同的信息量.
我们可以为每张图片动态地选择一种质量优化设置,找到质量和存储大小之间的理想平衡.有两种方法可以做到这一点:
自下而上:这些是通过处理 8 x 8 像素块级别的图像生成调谐量化表的算法.它们计算出丢失了多少理论上的质量,以及丢失的数据如何放大或消除,对人眼可见失真的多或少.
自上而下的:这些算法是将整张图片与其原始无失真版本进行比较,检测丢失了多少信息.通过迭代生成具有不同质量设置的候选图像,我们可以选择其中一张图片,作为满足某种评估算法的最低评估水平的图像.
我们评估了一种自下而上的算法,在实验中,在我们希望使用的质量范围的上限内没有产生合适的结果(尽管它似乎仍然具有中档图像质量的潜力, 这时编码器可以开始更冒险地去丢弃它的字节).关于这一策略的众多学术论文在90年代初就有发表,该方法对计算能力要求很高,并且走了选项 B 地址这类的捷径,例如不评估块之间的交互.
所以我们采取了第二种方法:使用对分的算法生成不同质量水平的候选图像,并通过使用 pyssim 函数来计算其结构相似性度量(SSIM),来评估每个候选图像的质量下降,直到该值处于可配置但阈值也还处于静态.这允许我们选择性地降低文件的平均大小(和平均质量),仅仅针对那些已经开始产生肉眼可识别的质量下降的图像.
在下图中,我们绘制了用3种不同质量方法生成的 2500 张图像的SSIM值的表.
1、用一种质量为 85 的初始方法作出原始图像,使用蓝线来绘制.
2、一种能降低文件大小,质量改为 80 的替代方法,用红线来绘制.
3、我们在最后选用了一种方法,使用橙色绘制动态质量的 SSIM 为 80 – 85 的图,即选择质量为 80 到 85(含)的图像,这是基于一种满足或超过的 SSIM 比率:该比率是预先计算的、使转换发生在图像范围中间的某个静态值.这样我们可以降低文件的平均大小,而不会降低那些质量最差的图片的质量.
济南IT培训课程结合行业技术趋势及企业用人需求的变化,及时更新,课程至少每半年进行一次升级,保证学习质量.
最新开班时间
- 北京
- 上海
- 广州
- 深圳
- 南京
- 成都
- 武汉
- 西安
- 青岛
- 天津
- 杭州
- 重庆
- 厦门
- 哈尔滨
- 济南
- 福州
- 沈阳
- 合肥
- 郑州
- 长春
- 苏州
- 大连
- 长沙
- 昆明
- 温州
- 太原
- 南昌
- 无锡
- 石家庄
- 南宁
- 中山
- 兰州
- 佛山
- 珠海
- 宁波
- 贵阳
- 保定
- 呼和浩特
- 东莞
- 洛阳
- 潍坊
- 烟台
- 运城