閱讀722 返回首頁    go 阿裏雲 go 技術社區[雲棲]


為何圖片經過OSS縮略之後尺寸變大了?——影響不同格式圖片文件大小的一些因素和實際示例

簡介

OSS提供了基本的圖片處理功能和圖片格式之間的轉換功能,在實際使用過程中,很多用戶使用OSS將原圖縮略之後輸出,在這個過程中也出現了很多用戶詢問為何縮略之後圖片尺寸變大,如這個例子:

原圖:https://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png

處理之後:https://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

首先我們分析最開頭遇到的這個例子。

原圖:https://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png

處理之後:https://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 https://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png?x-oss-process=image/resize,w_600  |grep Colors
  Colorspace: sRGB
  Colors: 27080
$ identify -verbose -unique https://batchtest.oss-cn-hangzhou.aliyuncs.com/example1.png  |grep Colors
  Colorspace: sRGB
  Colors: 256

可見顏色數目由256增長到了27080個。

例子2

原圖:https://batchtest.oss-cn-hangzhou.aliyuncs.com/example2.png

處理之後:https://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

原圖:https://batchtest.oss-cn-hangzhou.aliyuncs.com/example3.png

處理之後:https://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

最後更新:2017-04-28 23:21:44

  上一篇:go 漢字基因十節課
  下一篇:go 感覺aliyun的體驗越來越差