为何图片经过OSS缩略之后尺寸变大了?——影响不同格式图片文件大小的一些因素和实际示例

本文涉及的产品
对象存储 OSS,20GB 3个月
对象存储 OSS,内容安全 1000次 1年
对象存储 OSS,恶意文件检测 1000次 1年
简介: OSS提供了基本的图片处理功能和图片格式之间的转换功能,在实际使用过程中,很多用户使用OSS将原图缩略之后输出,在这个过程中也出现了很多用户询问为何缩略之后图片尺寸变大,本文主要通过一些示例解释了这种现象出现的原因和排查方法。

简介

OSS提供了基本的图片处理功能和图片格式之间的转换功能,在实际使用过程中,很多用户使用OSS将原图缩略之后输出,在这个过程中也出现了很多用户询问为何缩略之后图片尺寸变大,如这个例子:

原图:http://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png

处理之后:http://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png?x-oss-process=image/resize,w_600

原图经过OSS从640x427 缩放到 600x400之后size反而变大了很多,这是为什么呢?

下面我们结合不同图片格式的一些特点分析一下为什么会出现这样的情况。

格式对比

图片目前是一种多种编码格式并存的情况。目前在网络上广泛使用的主流格式有JPEG、PNG和WEBP三种,其他的类似BMP、GIF、TIFF等使用较少,这里暂时不讨论。

JPEG作为一种最常见的图片格式,出现的最早,几乎已经成为网络上的标准格式。但是在实际使用上有一个最大的问题,那就是不支持透明通道。

PNG是一种无损压缩的图片格式,最大的优势是支持模式多,可以支持RGB、灰度、索引等各种格式,同时可以自由选择叠加透明通道或者指定透明背景颜色,因此在图片质量要求较高的时候或者需要支持透明通道的时候PNG是最好的选择。

WEBP是Google大力推广的一种图片格式。WEBP作为一种现代图片格式,不仅运用了很多新的压缩方式,达到在同等效果下比JPEG减小很多尺寸,而且支持透明通道、无损压缩等之前只有PNG才支持的一些特性,因此在很多方面也得到了广泛的运用。

三种格式的功能对比如下:

image

尺寸影响因素

对于同一张片来说,使用JPEG和WEBP,尺寸影响因素除了图片长宽之外,最主要就是压缩的质量参数。但是对于PNG来说,影响的因素非常多。

PNG的是无损压缩,基本原理是首先对图片使用差分编码,然后对编码之后的数据使用LZ77+Huffman编码进行压缩。因此PNG图片的大小受到以下这些因素的影响:

  • 图片内容:因为重复性内容多的PNG图片会导致无法充分的压缩,因此文件大小会很大。
  • 位深:PNG支持16bit和8bit的类型。
  • 色彩空间:PNG支持24bit的真彩色、8bit的灰度、8bit的索引图像等类型,因此视觉效果相同的图片文件大小会非常悬殊。
  • 透明通道:带透明通道的PNG图片会比不带的多出很多像素,另外,如果仅仅指定透明背景色对图片文件大小几乎无影响。

下面会用结合实际遇到的一些例子来说明这些因素如何影响图片文件大小。

例子1

首先我们分析最开头遇到的这个例子。

原图:http://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png

处理之后:http://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png?x-oss-process=image/resize,w_600

可见原图大小为127K,缩放之后为335K。

这种问题调查首先要确定原图和缩放之后的一些详细信息,这里我们使用ImageMagicK这个工具集中的identify命令来查看对应的信息。工具官网见https://www.imagemagick.org/script/index.php

这里使用的命令是identify -verbose xxx.png。

原图的信息为:

 Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: PseudoClass
  Geometry: 640x427+0+0
  Units: Undefined
  Type: Palette
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit

再看处理之后的图片信息:

Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 600x400+0+0
  Units: Undefined
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit

这里可以看出区别,那就是原图的Type为Palette,处理之后的图片为TrueColor,这就是最大的差别,因为原图为索引类型,处理之后的图片为RGB真彩色,因此需要编码的像素点个数是索引类型的三倍,因此导致图片变大。

这种类型是最常见的图片变大的原因,造成一种原因一个很重要的因素是使用了PNG优化工具如ImageAlpha等,这些工具会将真彩色的PNG图片降采样到256种颜色然后压缩成索引类型以减少图片大小,这是一个有损的过程。但是在缩放过程中,缩略的过程会根据原像素计算出新的像素值,因此缩放算法会导致结果图片生成的颜色数目超过256种从而无法压缩成索引图像。

为了确定这一点,我们也可以使用identify工具来查看颜色数目:

$ identify -verbose -unique http://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png?x-oss-process=image/resize,w_600  |grep Colors
  Colorspace: sRGB
  Colors: 27080
$ identify -verbose -unique http://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png  |grep Colors
  Colorspace: sRGB
  Colors: 256

可见颜色数目由256增长到了27080个。

例子2

原图:http://batchtest.oss-cn-hangzhou.aliyuncs.com/example2.png

处理之后:http://batchtest.oss-cn-hangzhou.aliyuncs.com/example2.png?x-oss-process=image/resize,w_600

原图大小为283K,处理之后大小为335K。

首先还是按照上面一个例子的方法,检查一下图片格式信息。

这是原图的:

  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 640x427+0+0
  Units: Undefined
  Type: Palette
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit

这是处理之后的结果:

  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 600x400+0+0
  Units: Undefined
  Type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit

可见,两者的压缩类型是完全一致的,那是什么原因导致的问题呢?

这里需要使用另外一个工具,pngthermal,链接见https://encode.ru/threads/1725-pngthermal-pseudo-thermal-view-of-PNG-compression-efficiency

这个工具主要的功能是将PNG图片不同部分的压缩率使用可视化的方式展现出来,亮度越高的地方压缩率越低,我们针对两张图片用该工具分析的结果如下,上为原图,下为处理后图片:
99106583A707EB41B11ECCC125C4F8C6

BF0DD7BABC83E65DD239A01286BB665B

可见同样视觉效果的图片,压缩率差别很大,说明处理前的图片细节上重复较多,一般来说都是由于颜色数目导致的。为了确定这一点,使用上个例子的工具检查颜色数目,可以同样确定原图为256种颜色,处理后变成了27080种颜色。

其实本示例中的原图就是上一个例子的原图强制转换为RGB真彩色空间之后生成的。因为颜色只有256种,因此可供压缩的重复性信息较多,导致了处理后的图片比原图还大。

实际应用中,有很多美工生成的素材图片使用的颜色并不多,因此导致压缩率比较高,缩放之后就会出现类似的情况。

例子3

原图:http://batchtest.oss-cn-hangzhou.aliyuncs.com/example3.png

处理之后:http://batchtest.oss-cn-hangzhou.aliyuncs.com/example3.png?x-oss-process=image/format,webp

这里的示例是一个PNG转WEBP,原图大小为760字节,处理之后变成了1.3K。

首先还是使用identify工具查看两者的差别。

这是原图的:

  Format: PNG (Portable Network Graphics)
  Mime type: image/png
  Class: DirectClass
  Geometry: 92x34+0+0
  Units: Undefined
  Type: GrayscaleAlpha
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    gray: 8-bit
    alpha: 8-bit

这是处理之后的:

  Format: PAM (Common 2-dimensional bitmap format)
  Mime type: image/x-portable-pixmap
  Class: DirectClass
  Geometry: 92x34+0+0
  Units: Undefined
  Type: PaletteAlpha
  Base type: TrueColor
  Endianess: Undefined
  Colorspace: sRGB
  Depth: 8-bit
  Channel depth:
    red: 8-bit
    green: 8-bit
    blue: 8-bit
    alpha: 8-bit

这里可以看出一个非常明显的区别,原图是灰度图带上了透明通道,而处理之后的图片是RGB再带上透明通道。

原因是Webp并不支持灰度图带上透明通道这种类型,带上透明通道就将格式固定成了RGBA格式。因此导致了要保存的数据变大。

总结

从上文的例子可以看出,影响图片文件大小的因素很多,这里仅简单的列举了几个在应用中经常遇到的因素。

  • 例子1:索引类型PNG缩略之后变成RGB类型PNG,像素增多导致文件变大。
  • 例子2:颜色数目较小的PNG图片缩略之后颜色数目变多,压缩率下降导致文件变大。
  • 例子3:带透明通道的灰度PNG转换成WEBP之后变成RGBA格式,像素增多导致文件变大。

可以看到大部分和预期结果不符合的都是PNG格式的图片。

一般来说,同样视觉效果的图片文件大小,webp<jpeg<png。但是PNG支持的编码类型非常的灵活,可以根据实际应用的需求自由调整,网上也有很多优化PNG图片大小的工具,因此往往出现图片处理之后破坏了优化效果,导致处理之后反而文件变大的情况。因此这里建议使用PNG图片上有体积大小要求的场景把体积优化放在最后一步,最好保存多份不同分辨率的PNG素材以供调用,不要对图片处理之后的图片文件大小有强预期。如果碰到了图片文件大小上的问题,也可以使用本文介绍的工具自己手动进行分析。

这里最后再补充一个Google给出的图片使用格式的建议作为结束:

3BDF58995EDC3EB802ED84BB1D33F5C1

相关实践学习
借助OSS搭建在线教育视频课程分享网站
本教程介绍如何基于云服务器ECS和对象存储OSS,搭建一个在线教育视频课程分享网站。
目录
相关文章
|
2月前
|
存储 人工智能 开发工具
AI助理化繁为简,速取代码参数——使用python SDK 处理OSS存储的图片
只需要通过向AI助理提问的方式输入您的需求,即可瞬间获得核心流程代码及参数,缩短学习路径、提升开发效率。
1456 4
AI助理化繁为简,速取代码参数——使用python SDK 处理OSS存储的图片
|
2月前
|
存储 人工智能 缓存
AI助理直击要害,从繁复中提炼精华——使用CDN加速访问OSS存储的图片
本案例介绍如何利用AI助理快速实现OSS存储的图片接入CDN,以加速图片访问。通过AI助理提炼关键操作步骤,避免在复杂文档中寻找解决方案。主要步骤包括开通CDN、添加加速域名、配置CNAME等。实测显示,接入CDN后图片加载时间显著缩短,验证了加速效果。此方法大幅提高了操作效率,降低了学习成本。
5477 16
|
2月前
|
算法 Java Linux
java制作海报四:java BufferedImage 转 InputStream 上传至OSS。png 图片合成到模板(另一个图片)上时,透明部分变成了黑色
这篇文章主要介绍了如何将Java中的BufferedImage对象转换为InputStream以上传至OSS,并解决了png图片合成时透明部分变黑的问题。
122 1
|
4月前
|
存储 JavaScript 前端开发
Vue中实现图片上传,上传后的图片回显,存储图片到服务器 【使用对象存储OSS】
这篇文章介绍了在Vue中实现图片上传到阿里云OSS对象存储服务的完整流程,包括服务端签名直传的前提知识、后端设置、前端组件封装以及图片上传和回显的效果展示。
|
5月前
|
运维 Serverless 对象存储
函数计算产品使用问题之如何配合OSS实现接口收到的图片或文件直接存入OSS
函数计算产品作为一种事件驱动的全托管计算服务,让用户能够专注于业务逻辑的编写,而无需关心底层服务器的管理与运维。你可以有效地利用函数计算产品来支撑各类应用场景,从简单的数据处理到复杂的业务逻辑,实现快速、高效、低成本的云上部署与运维。以下是一些关于使用函数计算产品的合集和要点,帮助你更好地理解和应用这一服务。
|
5月前
|
机器学习/深度学习 人工智能 专有云
人工智能平台PAI使用问题之怎么将DLC的数据写入到另一个阿里云主账号的OSS中
阿里云人工智能平台PAI是一个功能强大、易于使用的AI开发平台,旨在降低AI开发门槛,加速创新,助力企业和开发者高效构建、部署和管理人工智能应用。其中包含了一系列相互协同的产品与服务,共同构成一个完整的人工智能开发与应用生态系统。以下是对PAI产品使用合集的概述,涵盖数据处理、模型开发、训练加速、模型部署及管理等多个环节。
|
1月前
|
分布式计算 Java 开发工具
阿里云MaxCompute-XGBoost on Spark 极限梯度提升算法的分布式训练与模型持久化oss的实现与代码浅析
本文介绍了XGBoost在MaxCompute+OSS架构下模型持久化遇到的问题及其解决方案。首先简要介绍了XGBoost的特点和应用场景,随后详细描述了客户在将XGBoost on Spark任务从HDFS迁移到OSS时遇到的异常情况。通过分析异常堆栈和源代码,发现使用的`nativeBooster.saveModel`方法不支持OSS路径,而使用`write.overwrite().save`方法则能成功保存模型。最后提供了完整的Scala代码示例、Maven配置和提交命令,帮助用户顺利迁移模型存储路径。
|
4月前
|
存储 机器学习/深度学习 弹性计算
阿里云EMR数据湖文件系统问题之OSS-HDFS全托管服务的问题如何解决
阿里云EMR数据湖文件系统问题之OSS-HDFS全托管服务的问题如何解决
|
5月前
|
消息中间件 分布式计算 DataWorks
DataWorks产品使用合集之如何使用Python和阿里云SDK读取OSS中的文件
DataWorks作为一站式的数据开发与治理平台,提供了从数据采集、清洗、开发、调度、服务化、质量监控到安全管理的全套解决方案,帮助企业构建高效、规范、安全的大数据处理体系。以下是对DataWorks产品使用合集的概述,涵盖数据处理的各个环节。
|
5月前
|
存储 运维 安全
阿里云OSS的优势
【7月更文挑战第19天】阿里云OSS的优势
243 2