參考
Web性能優(yōu)化:圖片優(yōu)化
Android bitmap(二) 常見(jiàn)圖片格式JPG PNG
一、PNG壓縮方式
參考
圖片壓縮之 PNG
PNG圖片壓縮對(duì)比分析
1.有損壓縮
根據(jù)資料顯示,tinypng、pngquant、ImageAlpha、pngnq都是有損壓縮,基本采用的都是quantization算法,將24位的PNG圖片轉(zhuǎn)換為8位的PNG圖片,減少圖片的顏色數(shù);
2.無(wú)損壓縮
pngcrush、optipng、pngout、advpng都是無(wú)損壓縮,采用的都是基于LZ/Huffman的DEFLATE算法,減少圖片IDAT chunk區(qū)域的數(shù)據(jù)。
一般有損壓縮的壓縮率會(huì)大大高于無(wú)損壓縮。
二、Laya ide 發(fā)布?jí)嚎s是有損壓縮

可以看出,laya內(nèi)置用pngquant來(lái)壓縮圖片,不過(guò)那些選項(xiàng)設(shè)置,真的沒(méi)讀懂。默認(rèn)設(shè)置壓縮出來(lái)的效果有問(wèn)題

GOOGLE了一下,具體參數(shù)含義
pngquant的參數(shù)說(shuō)明:
1.quality參數(shù)的作用是保證圖片經(jīng)過(guò)優(yōu)化處理后,圖片質(zhì)量的取值范圍(0~100)。取值越小,表示壓縮比率越大,同時(shí)的圖片的質(zhì)量也就越差。在測(cè)試過(guò)程中發(fā)現(xiàn),當(dāng)設(shè)置最低取值為60或65時(shí),部分圖片的質(zhì)量會(huì)嚴(yán)重下降,因此最終我選擇了70作為最低值。
2.speed參數(shù)的設(shè)置決定了圖片優(yōu)化的執(zhí)行速度,取值范圍為1~10,默認(rèn)值為3。其中10的執(zhí)行速度最快,對(duì)應(yīng)的壓縮比率最??;而1的執(zhí)行速度最慢,對(duì)應(yīng)的壓縮比率最大。在測(cè)試過(guò)程中發(fā)現(xiàn),無(wú)論我設(shè)置哪一個(gè)值它們的執(zhí)行時(shí)間都差不多,不過(guò)壓縮比率確實(shí)1的最大,10的最小,最后我選擇了一個(gè)較為折中的值:4。
實(shí)測(cè)效果:
在設(shè)置quality的取值范圍為70~95,以及speed為4的情況下,可以在盡可能不影響圖片質(zhì)量的前提下去縮減文件的大小。
在測(cè)試過(guò)程中,我們以PNG-8品質(zhì)為256的圖片為例,最終的圖片輸出可以降低70%左右的大?。◤?.78KB縮減到1.13KB)。
具體用法可參考一個(gè)不錯(cuò)的 png壓縮工具 pngquant 使用介紹 批量壓縮png
gulp腳本如下
var gulp = require('gulp');
var imagemin = require('gulp-imagemin');
var pngquant = require('imagemin-pngquant'); //png圖片壓縮插件
gulp.task('default', function () {
return gulp.src('src/images/*')
.pipe(imagemin({
progressive: true,
use: [pngquant()] //使用pngquant來(lái)壓縮png圖片
}))
.pipe(gulp.dest('dist'));
});
通過(guò)以上參數(shù)說(shuō)明,我把quality從50分別改成60,65,70試了一下。問(wèn)題又出現(xiàn)了,之前有張圖700多K,能壓縮到200多K。但改了這個(gè)quality之后,就不壓縮了,還是700多K.沒(méi)辦法,自己去找tinypng壓縮一下。
三、tinypng應(yīng)該是最好的有損壓縮
參考
圖片壓縮利器 —— TINYPNG 簡(jiǎn)介
gulp-tinypng-nokey
tinypng-nokey
自己搞了gulp腳本:
var gulp = require('gulp');
var tiny = require('gulp-tinypng-nokey');
gulp.task('image', function(cb) {
gulp.src('src/*.{png,jpg,jpeg}')
.pipe(tiny())
.pipe(gulp.dest('dist'));
});
//var gulp = require("gulp");
//var tingpng = require('gulp-tinypng');
//gulp.task("image", function () {
// return gulp.src("src/*.png")
// .pipe(tingpng('xK_CkxhgEQL9X0TnpHsevcUF0ClL'))
// .pipe(gulp.dest("dist"));
//});
gulp.task('default', ['image']);
tinypng盡量放到任務(wù)的最后一步,因?yàn)檫@個(gè)過(guò)程是要上傳圖片,再下載圖片的,和網(wǎng)絡(luò)穩(wěn)定有關(guān)
腳本執(zhí)行得很慢,因?yàn)橐蟼飨螺d。壓縮效果比pngquant還要小,紅色的紋不見(jiàn)了。不過(guò)有個(gè)漸變光的背景圖被壓殘了



三、推薦GUI工具limitPNG,支持有損和無(wú)損壓縮
PNG 極限壓縮工具 - limitPNG
gluttonyPNG
工具很好用,可惜沒(méi)有找到腳本,無(wú)法集成到gulp里
四、找一個(gè)無(wú)損壓縮的腳本
有損壓縮的效果,接受不了?,F(xiàn)在的目標(biāo)就是找一個(gè)支持無(wú)損壓縮的腳本!
在使用gulp進(jìn)行圖片優(yōu)化,作者提到了:
Smushit是Yahoo開(kāi)發(fā)的一款用來(lái)優(yōu)化PNG和JPG的插件,它的原理是移除圖片文件中不必要的數(shù)據(jù)。這是一個(gè)無(wú)損壓縮工具,這意味著優(yōu)化不會(huì)改變圖片的顯示效果和質(zhì)量。
var gulp = require('gulp');
var smushit = require('gulp-smushit');
gulp.task('smushit', function () {
return gulp.src('src/*')
.pipe(smushit({
verbose: true
}))
.pipe(gulp.dest('smushit-dist'));
});
但是我實(shí)測(cè),仍然是有損壓縮方式。和tinypng基本是一樣的。
然后,找到了 imagemin-optipng
gulp.task('optipng', function(cb) {
return gulp.src(resPath+'/**/*.*')
.pipe(jsFilter)
.pipe(imagemin({
progressive: true,
use: [imageminOptipng()]
}))
.pipe(jsFilter.restore)
.pipe(gulp.dest('dist'));
});
和gluttonyPNG無(wú)損壓縮結(jié)果一樣的,不過(guò)執(zhí)行速度卻慢多了,當(dāng)然方便在腳本中使用,所以最終采用了它。
五、jpg壓縮
tinypng雖然名字帶png,其實(shí)是能壓縮jpg的。optipng就不行了。然后看了一下LAYA IDE,用的是guetzli
參考
Google Guetzli 開(kāi)源新算法,可將JPEG文件縮小35%
Google開(kāi)源JPEG壓縮算法--Guetzli體驗(yàn)
此外,可能大家已經(jīng)注意到Guetzli對(duì)png的圖片壓縮比高達(dá)89%,原因是
- 該圖片為png類(lèi)型的圖片,而Guetzli算法針對(duì)的是jpeg圖片進(jìn)行壓縮,官方文檔中的說(shuō)法是“sRGB profile with a gamma of 2.2”,而png圖片除了rgb通道還有alpha通道,猜測(cè)可能是因?yàn)閴嚎s算法的輸出是jpeg,因此將alpha通道進(jìn)行了過(guò)濾,才有如此高的壓縮比。
- jpeg圖片本身就是有損壓縮的格式,而png是無(wú)損壓縮的格式,因此用png圖片做測(cè)試有更高的壓縮空間。
我自己測(cè)試了一下,原圖是362K。用tinypng可以壓縮到72K,用guetzli壓縮到174K。在不放大的情況下,是看不出區(qū)別的。當(dāng)然放大到700%時(shí),就能看出tinypng是有損壓縮的
const gulp = require('gulp');
const imagemin = require('gulp-imagemin');
const imageminGuetzli = require('imagemin-guetzli');
gulp.task('default', () =>
gulp.src('images/*')
.pipe(imagemin([imageminGuetzli()]))
.pipe(gulp.dest('dist/images'))
);