App圖片壓縮裁剪原理和上傳方案损话,以及那些有趣的事兒...

本文始發(fā)于我的博文App圖片壓縮裁剪原理和上傳方案侦啸,以及那些有趣的事兒...,現(xiàn)轉(zhuǎn)發(fā)至此丧枪。

目錄

  • App怎么壓縮質(zhì)量光涂?
    • iOS和Android壓縮接口
    • 實驗一
  • 如何計算圖片的大小拧烦?
  • JPEG&JFIF壓縮做了什么忘闻?
    • 色彩空間轉(zhuǎn)換
    • 縮減取樣
    • 離散余弦變換
    • 量化
    • 編碼
  • App怎么裁剪分辨率?
  • 圖片壓縮裁剪上傳方案
    • 實驗一:上傳速度
    • 實驗二:用戶設(shè)備主要分辨率
    • 實驗三:上傳的照片的主要分辨率
    • 實驗四:壓縮質(zhì)量的大致規(guī)律
    • 實驗五:等比例裁剪后壓縮質(zhì)量的大致規(guī)律
    • 實驗六:WebP壓縮
    • 制定方案
  • 總結(jié)
  • 附錄
    • 圖像的一些概念澄清
    • 壓縮算法概念
    • 微信圖片處理規(guī)律
    • Base64編碼后大小
    • iOS的pt與Android的sp
    • Android圖片質(zhì)量會比iPhone的差恋博?
    • iOS的UIImage保存圖片問題
    • 壓縮再壓縮做了什么

最近有反饋說App上傳圖片偶爾會失敗齐佳,特別是在網(wǎng)速慢和iPhone 6s的機器上。有些提示是“413 Request Entity Too Large”债沮,Request大小1.15MB炼吴。之前只是簡單地壓到0.7,沒有做裁剪等其他處理疫衩。

所以這幾天整體研究下iOS和Android的圖片壓縮裁剪和JPEG壓縮原理缺厉,也稍微找了微信發(fā)圖片的規(guī)律,越深入發(fā)現(xiàn)越多有趣的東西隧土,問題一環(huán)扣一環(huán)。

App怎么壓縮質(zhì)量命爬?

最先接觸的是壓縮質(zhì)量曹傀,所以看下壓縮質(zhì)量做了什么。

iOS和Android壓縮接口

iOS:

UIImageJPEGRepresentation(UIImage * __nonnull image, CGFloat compressionQuality);  
// return image as JPEG. May return nil if image has no CGImageRef or invalid bitmap format. compression is 0(most)..1(least)

Android:

/** 
    * Write a compressed version of the bitmap to the specified outputstream. 
    * If this returns true, the bitmap can be reconstructed by passing a 
    * corresponding inputstream to BitmapFactory.decodeStream(). Note: not 
    * all Formats support all bitmap configs directly, so it is possible that 
    * the returned bitmap from BitmapFactory could be in a different bitdepth, 
    * and/or may have lost per-pixel alpha (e.g. JPEG only supports opaque 
    * pixels). 
    * 
    * @param format   The format of the compressed image 
    * @param quality  Hint to the compressor, 0-100. 0 meaning compress for 
    *                 small size, 100 meaning compress for max quality. Some 
    *                 formats, like PNG which is lossless, will ignore the 
    *                 quality setting 
    * @param stream   The outputstream to write the compressed data. 
    * @return true if successfully compressed to the specified stream. 
*/
compress(CompressFormat format, int quality, OutputStream stream)

從官方注釋看饲宛,iOS的compressionQuality取值從0-1皆愉,且“1”注明是least,也就是說“1”不是不壓縮艇抠,而是壓縮強度最弱幕庐;Android的quality取值0-100,也是100代表最大質(zhì)量家淤,不是不壓縮异剥。最后面測試也驗證了這個問題,而不是網(wǎng)上很多文檔說的不壓縮絮重。我們先統(tǒng)稱compressionQuality和quality為質(zhì)量系數(shù)冤寿,下文也是歹苦。

實驗一

于是拍了一張照片A,然后Android和iOS都壓縮得到照片B督怜。

對比了A殴瘦、B兩張圖,想看看到底影響了什么:

寬度:2448像素
高度:3264像素
分辨率:72像素/英寸
文檔:22.9MB
通道:3(RGB)

注:需弄明白附錄的關(guān)于圖像的一些概念澄清号杠。

兩張照片看到的參數(shù)都一樣蚪腋,那為什么它們的文件大小會不一樣呢?(過程中發(fā)現(xiàn)iOS的UIImage會做多一些工作姨蟋,使得實驗結(jié)果有誤屉凯,原因后面會提到。)(用Picasa看圖軟件可以查看質(zhì)量芬探,數(shù)值上看到等于我們的質(zhì)量系數(shù))所以就想到第二個問題神得,文件大小怎么計算的?由什么決定偷仿?

如何計算圖片的大辛ú尽?

總分辨率 * 像素表示的位數(shù)酝静。

像素表示的位數(shù):這就涉及到色彩模式节榜,比較常見有RGB、CMYK别智、YUV等宗苍。RGB一般用RGB24(還有RGB555、RGB565薄榛、RGB32)讳窟,即紅綠藍都分別用8位表示,所以用了24位表示一個像素敞恋,可以組合出2^24種顏色丽啡。

上面兩張圖水平有2448個像素,垂直有3264個像素硬猫,每個像素用24b表示补箍,按這公式大小應(yīng)該都是:2448x3264x24b=23970816B=22.86MB。為什么呢啸蜜?

后來明白坑雅,原來這公式是算位圖的占用空間大小,而JPEG&JFIF是將位圖壓縮衬横,不僅壓縮圖像質(zhì)量還壓縮圖像占用空間(后面會講到)裹粤。也就是說圖像壓縮不等于壓縮質(zhì)量和分辨率,還有壓縮占用空間蜂林。

網(wǎng)上查到JFIF文件沒有計算大小的公式蛹尝,因為壓縮質(zhì)量和壓縮后大小沒有特定關(guān)系后豫,如線性關(guān)系。那么JPEG&JFIF壓縮做了什么突那?這個質(zhì)量到底代表了什么挫酿?

JPEG&JFIF壓縮做了什么?

其實JPEG&JFIF做了兩件事情:

  1. 去掉視覺上的冗余信息
  2. 去掉數(shù)據(jù)本身結(jié)構(gòu)的冗余

第一步實現(xiàn)通過色彩空間轉(zhuǎn)換愕难、縮減取樣早龟、離散余弦變換、量化猫缭,第二步實現(xiàn)通過編碼葱弟。

其實這部分可以選擇跳過,只是我為了理解壓縮質(zhì)量是怎么體現(xiàn)的而去看的猜丹,后面也發(fā)現(xiàn)理解后很多問題都很清晰明白芝加。

色彩空間轉(zhuǎn)換

JPEG需要YUV色彩模式,所以需要將RGB轉(zhuǎn)成YUV:

  • Y=0.299R'+0.587G'+0.114B'
  • U=-0.147R'-0.289G'+0.436B'
  • V=0.615R'-0.515G'-0.100B'

縮減取樣

YUV分別代表亮度射窒、色度藏杖、飽和度,因為人類的眼睛對于亮度差異的敏感度高于色彩變化脉顿,所以一般會對U蝌麸、V進行縮減采樣。在JPEG上這種縮減取樣的比例可以是4:4:4(無縮減取樣)艾疟、4:2:2来吩、4:2:0。所以經(jīng)常會看到Y(jié)UV444蔽莱,YUV422和YUV420等弟疆。

離散余弦變換

將每個8x8的子區(qū)域轉(zhuǎn)換到頻率空間,這部分是無損的盗冷。

-415 -30 -61 27 56 -20 -2 0
4 -22 -61 10 13 -7 -9 5
-47 7 77 -25 -29 10 5 -6
-49 12 34 -15 -10 6 2 2
12 -7 -13 -4 -2 2 -3 3
-8 3 2 -6 -2 1 4 2
-1 0 0 -2 -1 -3 4 -1
0 0 -1 -4 -1 0 1 2

量化

量化是有損的過程兽间,也是失真的主要原因。上面矩陣中每個值都是幅度正塌,量化是利用人眼特點在高頻率上降低信息的數(shù)量(簡單地把頻率領(lǐng)域上每個成分,除以一個對于該成分的常數(shù)就可完成恤溶,且接著舍位取最接近的整數(shù))乓诽,與一個基本矩陣運算然后得到一個新的矩陣,該新矩陣數(shù)據(jù)基本集中在左上角咒程。

其實量化做的就是減少非0系數(shù)幅度和增加0值系數(shù)的個數(shù)
我們接口中的質(zhì)量系數(shù)就是和這里的基本矩陣有關(guān)。

編碼

Z掃描0值行程長度編碼牺蹄、哈夫曼編碼。
Z掃描0值行程長度編碼利用了量化后矩陣的特點奶段,使得0值的都能串在最后面,對于過早結(jié)束的最后用EOB表示剥纷。
這一步就是壓縮文件的占用空間痹籍。

App怎么裁剪分辨率?

弄清楚壓縮質(zhì)量問題后晦鞋,我們知道蹲缠,影響位圖的大小有分辨率,那么減少分辨率也就能使壓縮得更小了悠垛。注意這里裁剪分辨率不等于裁剪圖片线定,不會丟失圖片的某一部分。

iOS:

UIGraphicsBeginImageContext(newSize);
[imageFixed drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Android:

Bitmap image = BitmapFactory.decodeStream(file);
int bitmapWidth = image.getWidth();
int bitmapHeight = image.getHeight();
Matrix matrix = new Matrix();
matrix.postScale(scaleRatio, scaleRatio);
Bitmap scaledBitmap = Bitmap.createBitmap(image, 0, 0, bitmapWidth, bitmapHeight, matrix, false);

我們是等比例裁剪确买,比例和裁剪后占用空間大小并不一定成線性關(guān)系斤讥,這個裁剪具體怎么實現(xiàn)的和每個像素的質(zhì)量有關(guān)系。

圖片壓縮裁剪上傳方案

明白一個圖片的清晰度等受什么影響之后湾趾,可以來定下方案了芭商,但是還得做些測試獲取數(shù)據(jù),依據(jù)數(shù)據(jù)結(jié)果來定方案撑帖。

實驗一:上傳速度

我們用Charles模擬了各種網(wǎng)絡(luò)環(huán)境下上傳相同照片的網(wǎng)速:

| 環(huán)境 | wifi | 8M | 16M | 32M |
| :----: | :----: | :---: | :----: |
| 速度KB/s | 754.78 | 115.4 | 115.78 | 116.25 |

| 環(huán)境 | 32M光纖 | 100M光纖 | 3G | 4G |
| :----: | :----: | :---: | :----: |
| 速度KB/s | 174.65 | 167.33 | 114.18 | 174.73 |

這些不等價于我們用戶的網(wǎng)速平均值蓉坎,而且只取一次樣本,所以只是作為參考胡嘿。

實驗二:用戶設(shè)備主要分辨率

因為照片都是在用戶設(shè)備上看的蛉艾,所以了解下用戶的主流分辨率,將分辨率裁剪到趨近或稍大于該主流分辨率會比較適合衷敌。iOS和Android都取接近的值勿侯。

在友盟查看了我們的應(yīng)用的相關(guān)數(shù)據(jù):

  • Android,較大占比的是寬度1080像素和720像素的設(shè)備缴罗。寬度1080像素的助琐,新增用戶占比49.69%,啟動次數(shù)占比44.29%面氓;寬度720像素的兵钮,新增用戶占比32.47%,啟動次數(shù)占比37.76%舌界。
  • iOS掘譬,較大占比的是寬度1242像素、750像素和640像素的設(shè)備呻拌。寬度1242像素的葱轩,新增用戶占比31.84%,啟動次數(shù)占比26.91%;寬度750像素的靴拱,新增用戶占比36.20%垃喊,啟動次數(shù)占比31.59%;寬度640像素的袜炕,新增用戶占比20.36%本谜,啟動次數(shù)占比20.84%。

實驗三:上傳的照片的主要分辨率

找下上傳的照片的主要分辨率妇蛀,可以針對這些分辨率去確定和衡量方案耕突。
也是在友盟上看我們的應(yīng)用的數(shù)據(jù):

  • iOS主流機型是iPhone6、iPhone6s评架、iPhone6 Plus眷茁、iPhone6s Plus,占到70%左右纵诞。它們的拍照分辨率分別是2448x3264上祈,3024x4032。
  • Android相對較碎片化浙芙,只能是針對最大的分辨率去衡量登刺。

實驗四:壓縮質(zhì)量的大致規(guī)律

2448x3264照片壓縮后的數(shù)據(jù)大小(單位B):

壓縮強度 圖片1 圖片2 圖片3 圖片4
0.1 197777 174464 152897 195214
0.2 212779 183532 163225 209426
0.3 253658 205512 196188 248320
0.4 360091 256013 283607 349968
0.5 498199 336823 390525 485286
0.6 724491 488737 548437 698421
0.7 1209508 883664 936968 1161342
0.8 1475669 1063724 1130241 1415084
0.9 1700461 1247600 1334143 1636293
1.0 4568157 3629379 4139209 4433556
原圖占用 1714688 1257647 1353635 1647936

3024x4032照片壓縮后的數(shù)據(jù)大形撕簟(單位B):

壓縮強度 圖片5 圖片6 圖片7 圖片8
0.1 551527 325434 296792 492494
0.2 619307 352608 328183 547533
0.3 785915 422342 416459 683265
0.4 1061504 537826 589206 931686
0.5 1408297 891288 839938 1290788
0.6 2071014 973894 1108102 1607344
0.7 2547536 1228021 1756824 2479774
0.8 2652258 1320258 1831889 2617015
0.9 3336839 1603754 2212214 3079872
1.0 7282230 4337074 5787540 7962849
原圖占用 2635183 1511290 1860418 2641699
  • 會出現(xiàn)壓縮出來反而比原圖大的問題纸俭,后面會討論
  • 在沒有裁剪的情況下,壓到0.6依舊不是太理想南窗,特別是分辨率更高的照片揍很。
  • 在excel表格中將數(shù)據(jù)組成折線圖,可以看出在0.9万伤、0.8的時候下降幅度較大窒悔,后面相對平緩一點。

實驗五:等比例裁剪后壓縮質(zhì)量的大致規(guī)律

2448x3264照片等比例壓縮到寬度1224像素時的數(shù)據(jù)大械新颉(單位B):

壓縮強度 圖片1 圖片2 圖片3 圖片4
0.1 58975 52025 43301 60029
0.2 64446 55583 46529 65347
0.3 76982 63805 55494 77891
0.4 99499 77605 76695 100042
0.5 129826 95116 103949 129597
0.6 173036 120654 144188 173569
0.7 246847 174977 209876 249223
0.8 303546 208392 261322 308841
0.9 411181 294795 358003 420013
1.0 1574657 1280563 1536779 1566585
原圖占用 1714688 1257647 1353635 1647936

3024x4032照片等比例壓縮到寬度1224像素時的數(shù)據(jù)大屑蛑椤(單位B):

壓縮強度 圖片5 圖片6 圖片7 圖片8
0.1 111697 70802 54321 121994
0.2 127179 77524 61810 136869
0.3 163959 94048 79713 172194
0.4 225870 122258 113295 230197
0.5 302097 157160 155152 300772
0.6 395440 202312 210836 385183
0.7 524345 273895 295530 505417
0.8 623839 323884 363596 593923
0.9 777293 420943 481205 745946
1.0 2184791 1530139 1774130 2291622
原圖占用 2635183 1511290 1860418 2641699
  • 可以看到裁剪這個分辨率后壓縮質(zhì)量0.6的大小相對可接受,而且圖片質(zhì)量影響也較小虹钮。
  • 在這個分辨率下聋庵,壓縮質(zhì)量0.8時基本壓縮到1/4至1/5。

實驗六:WebP壓縮

WebP據(jù)稱在同等質(zhì)量下大小可以壓縮至JPEG的2/3芙粱。在iOS和Android都做了WebP的壓縮測試祭玉,發(fā)現(xiàn)壓縮速度非常慢,需要20s-35s宅倒,這是很不可接受的。上網(wǎng)查到WebP的壓縮效率的確較慢,是JPEG的8倍左右拐迁,而且相比JPEG需要耗費更多的系統(tǒng)性能蹭劈。所以本來想用WebP做兜底的方案暫時落空。

制定方案

方案的目的是:

  1. 上傳圖片不超時
  2. 處理后質(zhì)量清晰度可接受
  3. 縮短上傳耗時

結(jié)合實驗結(jié)論:

  • 根據(jù)實驗一线召,平均上傳速度100KB/s铺韧,另外我們測試很差情況下有15KB/s的情況。我們的接口超時30s缓淹,所以可接受的圖片大小最大為450KB哈打。
  • 根據(jù)實驗二,等比例寬度取750-1242像素比較合適讯壶。
  • 根據(jù)實驗三料仗、四、五伏蚊,等比例裁剪到寬度1224像素后壓縮至0.6立轧、0.7大小相對可接受。質(zhì)量相對可接受(主觀感受)躏吊。
  • JPG氛改、PNG和GIF圖片的基本原理及優(yōu)化方法講到,通常建議JPG質(zhì)量最好是在60左右的原因比伏。當(dāng)在Photoshop中把質(zhì)量設(shè)置低于51的時候胜卤,它就會執(zhí)行另一個叫做“降色采樣”的優(yōu)化算法,它會在8個像素周圍平均采樣赁项,這樣會在邊緣產(chǎn)生雜色葛躏。

定下方案:

  1. 照片寬度大于1224像素(因為iPhone6照片寬度2448所以想取個可以整除的)時等比例裁剪寬度成1224。因為分辨率太大甚至兩倍于手機分辨率實際沒有任何用處肤舞。
  2. 壓縮質(zhì)量系數(shù)至0.8(80)看下大小是否小于300KB紫新,排除一些小分辨率的照片。小于則上傳李剖,大于則繼續(xù)壓縮芒率,取0.7(70),排除一些中等的篙顺,如果還大于則取0.6(60)后不判斷直接上傳偶芍。根據(jù)上面的實驗可以看到在寬度1224像素下基本都會小于300KB,大于的則處于450KB內(nèi)德玫,且450KB是網(wǎng)速最差的情況匪蟀,因此基本可以保證上傳。

總結(jié)

方案目前看壓縮的質(zhì)量和時間控制都相對較好宰僧,但是還要繼續(xù)觀察一段時間看需不需要再調(diào)整參數(shù)材彪。在這過程中理清了很多概念,了解了圖片壓縮過程中發(fā)生了什么事情,挺有趣的段化,根本停不下來嘁捷。

附錄

文中涉及到的一些概念以及發(fā)現(xiàn)的一些其他相關(guān)事情。

圖像的一些概念澄清

其實圖像真正的信息是它的總分辨率(圖像寬度x圖像高度)和分辨率(水平分辨率&垂直分辨率)显熏,而涉及到英寸雄嚣、厘米等長度單位時的大小,其實不是圖像的信息喘蟆,只是在涉及到外部缓升,比如打印、設(shè)備屏幕顯示等等時蕴轨,換算出來的港谊。

  • 水平分辨率&垂直分辨率

分辨率一般單位ppi(也有dpi),即每英寸上多少個像素尺棋。水平分辨率即水平方向上像素個數(shù)/水平長度封锉,垂直分辨率同理。一般水平分辨率和垂直分辨率是相等的膘螟,所以日常也簡稱為分辨率成福。dpi即每英寸上多少點。這兩個單位根據(jù)不同顯示設(shè)備有換算關(guān)系荆残。

  • 圖像寬度&圖像高度

其實標(biāo)準(zhǔn)些奴艾,講寬度&高度時一般是講圖像水平/垂直上有多少個像素。如一張2448x3264的照片内斯,則寬度是2448像素蕴潦,高度是3264像素。也有講寬度是86.36厘米俘闯,高度是115.15厘米潭苞,一般在打印照片等情況下。

  • 分辨率

日常講分辨率時其實可以指很多情況真朗,一般指圖像寬度x高度此疹,如2448x3264,指水平上有2448個像素遮婶,垂直上有3264個像素蝗碎。

壓縮算法概念

  • JPEG

一個名稱為Joint Photographic Experts Group的組織,也是一種壓縮算法旗扑。JPEG本身只有描述如何將一個視頻轉(zhuǎn)換為字節(jié)的數(shù)據(jù)流(streaming)蹦骑,但并沒有說明這些字節(jié)如何在任何特定的存儲媒體上被封存起來。JPEG有有損壓縮和無損壓縮臀防,無損壓縮的沒有得到什么支持眠菇,所以一般講JPEG指它的有損壓縮边败。

  • JFIF

JPEG File Interchange Format,JPEG文件交換格式捎废,詳細(xì)說明如何從一個JPEG流放闺,產(chǎn)出一個適合于電腦存儲和傳輸?shù)奈募?/strong>。一般后綴有.jpeg缕坎、.jpg、.jfif以及.jif篡悟。

  • Bitmap

又稱柵格圖谜叹,是使用像素陣列來表示的圖像。非壓縮格式搬葬,從左往右從上往下掃描荷腊,占用較大存儲空間。

https://zh.wikipedia.org/wiki/JPEG
https://zh.wikipedia.org/wiki/%E4%BD%8D%E5%9B%BE

微信圖片處理規(guī)律

經(jīng)過簡單測試發(fā)現(xiàn)急凰,在微信女仰,A發(fā)一張原圖給B時,B直接保存縮略圖:

  • iOS版的微信保存下來是等比例壓縮高度為800抡锈,質(zhì)量80疾忍。
  • Android版的微信保存下來是等比例壓縮高度為1280,質(zhì)量80床三。

朋友圈的圖片保存下來一罩,都是等比例到高1280像素,質(zhì)量和大小還沒找到規(guī)律撇簿。
為什么微信是取高固定而不是寬呢聂渊?可以思考下。

Base64編碼后大小

我們現(xiàn)在還用著Base64編碼圖像數(shù)據(jù)四瘫,后面需改成提交表單方式汉嗽。

Base64要求把每三個8Bit的字節(jié)轉(zhuǎn)換為四個6Bit的字節(jié)(38 = 46 = 24),然后把6Bit再添兩位高位0找蜜,組成四個8Bit的字節(jié)饼暑,也就是說,轉(zhuǎn)換后的字符串理論上將要比原來的長1/3锹杈。

iOS的pt與Android的sp

我在iOS所有設(shè)備的分辨率撵孤、尺寸和縮放因子,放大模式區(qū)別和6P實際分辨率文章里講了iOS設(shè)備的pt和px關(guān)系竭望。
iOS的pt是開發(fā)單位邪码,一個邏輯point對應(yīng)一個點dot。@1x設(shè)備上一個pt上顯示1個px(像素)咬清,@2x上一個pt顯示2個px闭专,@3x上顯示3個px奴潘。平時在storyboard上設(shè)置時指的都是pt。

Android的sp一種基于屏幕密度的抽象單位影钉。

Android圖片質(zhì)量會比iPhone的差画髓?

為什么Android的圖片質(zhì)量會比iPhone的差?平委、[Android算法] 【04/28 bug修改】android圖片壓縮終極解決方案奈虾、Android圖片編碼機制深度解析(Bitmap,Skia廉赔,libJpeg)三篇文章中講了Android系統(tǒng)在壓縮上的一些不為人知的問題肉微。

大致是,Android編碼保存圖片就是通過Java層函數(shù)——Native層函數(shù)——Skia庫函數(shù)——對應(yīng)第三方庫函數(shù)(例如libjpeg)蜡塌,這一層層調(diào)用做到的碉纳。 libjpeg在壓縮圖像時,有一個參數(shù)叫optimize_coding馏艾,如果設(shè)置optimize_coding為TRUE劳曹,將會使得壓縮圖像過程中基于圖像數(shù)據(jù)計算哈弗曼表,由于這個計算會顯著消耗空間和時間琅摩,默認(rèn)值被設(shè)置為FALSE铁孵。對于當(dāng)時的計算設(shè)備來說,空間和時間的消耗可能是顯著的房资,但到今天库菲,這似乎不應(yīng)再是問題。但谷歌的Skia項目工程師們對optimize_coding在Skia中默認(rèn)的等于了FALSE志膀,這就意味著更差的圖片質(zhì)量和更大的圖片文件熙宇。還有其他和iOS的比較可以看下。

也講到了Android可以替換libjpeg庫達到設(shè)置為TRUE的目的溉浙。

iOS的UIImage保存圖片問題

起初發(fā)現(xiàn)壓縮后保存圖片烫止,不同壓縮質(zhì)量系數(shù),得出來的文件大小趨勢和計算出的大小趨勢不同戳稽,所以懷疑使用NSData初始化UIImage時多做了什么馆蠕。

NSData *imageData06 = UIImageJPEGRepresentation(scaledImage, 0.6);
UIImage *image06 = [UIImage imageWithData:imageData06];
UIImageWriteToSavedPhotosAlbum(image06, nil, nil, nil);

通過軟件發(fā)現(xiàn),不同壓縮質(zhì)量系數(shù)惊奇,得出來的NSData保存成UIImage圖片互躬,看到的質(zhì)量都是92,按道理應(yīng)該是對應(yīng)的質(zhì)量系數(shù)才對颂郎。于是想將NSData保存成文件到目錄吼渡,讀取出文件大小。

NSString *documents = [NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES) objectAtIndex:0];
NSString *filePath = [documents stringByAppendingPathComponent:@"image.jpg"];
NSData *imageData = UIImageJPEGRepresentation(image, 0.7);
NSError *error = nil;
[imageData writeToFile:filePath options:NSDataWritingAtomic error:&error];
if (error != nil) {
    NSLog(@"error = %@", error);
}else {
    NSLog(@"success");
}
NSLog(@"imageData = %u", (unsigned)imageData.length);
NSFileManager* manager = [NSFileManager defaultManager];
if ([manager fileExistsAtPath:filePath]){
    unsigned long long size = [[manager attributesOfItemAtPath:filePath error:nil] fileSize];
    NSLog(@"0.7后文件大小 %llu", size);
}
UIImage *imageFromData = [UIImage imageWithData:imageData];
UIImageWriteToSavedPhotosAlbum(imageFromData, nil, nil, nil);
UIImage *imageRead = [[UIImage alloc] initWithContentsOfFile:filePath];
UIImageWriteToSavedPhotosAlbum(imageRead, nil, nil, nil);

讀取文件大小size和NSData大小imageData.length打印一致乓序,而與imageRead寺酪、imageFromData的大小不一樣坎背,因此可以證明UIImage這個對象本身還做了其他事情。

AFNetworking2.0源碼解析這篇文章的截圖顯示寄雀,UIImage的imageWithData方法堆棧顯示還調(diào)用了哈夫曼解碼得滤。

壓縮再壓縮做了什么

  1. 首先談下看圖軟件怎么展示圖片。打開.jpg圖片時盒犹,看圖軟件將文件轉(zhuǎn)換成位圖才顯示出來懂更,即把量化表矩陣與基本轉(zhuǎn)化矩陣運算得出圖片當(dāng)前的位圖(因為經(jīng)過了壓縮,所以該位圖與原位圖不同)急膀。
  2. 壓縮后再壓縮也是膜蛔,先將圖片變回位圖,再將位圖按現(xiàn)在的壓縮質(zhì)量系數(shù)壓縮脖阵。
  3. 所以壓縮后的圖片有可能變大,我猜測原因是墅茉,壓縮前的占用空間壓縮率較大命黔,而再壓縮時選的質(zhì)量系數(shù)較大,導(dǎo)致壓縮占用空間率(即壓縮的第二步)較小就斤,所以導(dǎo)致質(zhì)量其實是變差了悍募,但是占用空間反而可能變大。

變大的例子如:本來圖片A大小500KB洋机,壓縮質(zhì)量系數(shù)選擇0.7坠宴,得到B圖片90KB,再拿這張B圖片去壓绷旗,壓縮質(zhì)量系數(shù)1.0喜鼓,得出C圖片。前面我們說壓縮不僅壓縮質(zhì)量衔肢,還壓縮占用空間庄岖。如果第一次壓縮的壓縮質(zhì)量比例跟第二次壓縮的比例的差值,比第一次壓縮的壓縮占用空間比例跟第二次的壓縮占用空間比例的差值小角骤,那么C圖片就會比B圖片大隅忿。因為雖然C圖片質(zhì)量比B圖片質(zhì)量差點,但是B圖片的空間壓縮得比C圖片大比較多邦尊。

-END-
歡迎到我的博客交流:http://zackzheng.info

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末背桐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蝉揍,更是在濱河造成了極大的恐慌链峭,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,378評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件又沾,死亡現(xiàn)場離奇詭異熏版,居然都是意外死亡纷责,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,356評論 2 382
  • 文/潘曉璐 我一進店門撼短,熙熙樓的掌柜王于貴愁眉苦臉地迎上來再膳,“玉大人,你說我怎么就攤上這事曲横∥蛊猓” “怎么了?”我有些...
    開封第一講書人閱讀 152,702評論 0 342
  • 文/不壞的土叔 我叫張陵禾嫉,是天一觀的道長灾杰。 經(jīng)常有香客問我,道長熙参,這世上最難降的妖魔是什么艳吠? 我笑而不...
    開封第一講書人閱讀 55,259評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮孽椰,結(jié)果婚禮上昭娩,老公的妹妹穿的比我還像新娘。我一直安慰自己黍匾,他們只是感情好栏渺,可當(dāng)我...
    茶點故事閱讀 64,263評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著锐涯,像睡著了一般磕诊。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上纹腌,一...
    開封第一講書人閱讀 49,036評論 1 285
  • 那天霎终,我揣著相機與錄音,去河邊找鬼升薯。 笑死神僵,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的覆劈。 我是一名探鬼主播保礼,決...
    沈念sama閱讀 38,349評論 3 400
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼责语!你這毒婦竟也來了炮障?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,979評論 0 259
  • 序言:老撾萬榮一對情侶失蹤坤候,失蹤者是張志新(化名)和其女友劉穎胁赢,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體白筹,經(jīng)...
    沈念sama閱讀 43,469評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡智末,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,938評論 2 323
  • 正文 我和宋清朗相戀三年谅摄,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片系馆。...
    茶點故事閱讀 38,059評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡送漠,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出由蘑,到底是詐尸還是另有隱情闽寡,我是刑警寧澤,帶...
    沈念sama閱讀 33,703評論 4 323
  • 正文 年R本政府宣布尼酿,位于F島的核電站爷狈,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏裳擎。R本人自食惡果不足惜涎永,卻給世界環(huán)境...
    茶點故事閱讀 39,257評論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望鹿响。 院中可真熱鬧羡微,春花似錦、人聲如沸抢野。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,262評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽指孤。三九已至,卻和暖如春贬堵,著一層夾襖步出監(jiān)牢的瞬間恃轩,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工黎做, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留叉跛,地道東北人。 一個月前我還...
    沈念sama閱讀 45,501評論 2 354
  • 正文 我出身青樓蒸殿,卻偏偏與公主長得像筷厘,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子宏所,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 42,792評論 2 345

推薦閱讀更多精彩內(nèi)容

  • 問答題47 /72 常見瀏覽器兼容性問題與解決方案酥艳? 參考答案 (1)瀏覽器兼容問題一:不同瀏覽器的標(biāo)簽?zāi)J(rèn)的外補...
    _Yfling閱讀 13,728評論 1 92
  • 版本記錄 前言 只要是做圖片的或者與圖片相關(guān)的霞玄,那么圖片的格式就是一個不可以繞過的問題骤铃,我們見過很多的圖片格式拉岁,但...
    刀客傳奇閱讀 14,156評論 0 5
  • 非原創(chuàng),只是整理惰爬,如果里面發(fā)現(xiàn)引用的內(nèi)容沒有標(biāo)識出來喊暖,歡迎指出。 一补鼻、基本知識 (1)兩種圖片: 1)矢量圖: 矢...
    風(fēng)再起時ME閱讀 2,437評論 0 19
  • LZ-Says:小沈陽版程序員~~~程序員其實可痛苦的了......需求一做一改哄啄,一個月就過去了;嚎~需求再一改一...
    靜心Study閱讀 3,827評論 1 14
  • 好久沒寫了风范,主要是人懶了咨跌,一有時間就玩手機~過去幾天,經(jīng)歷了低谷硼婿,各種面試的失敗锌半,讓我已經(jīng)有了無力感。想找各種人說...
    哈啦呢閱讀 274評論 0 1