VSCodeでweb向けに画像最適化

Node.jsとgulpを使っていい感じに画像を最適化する。
実際に使用した結果130MBくらいあったHexoで作ったイラストポートフォリオサイトが30MBまで減った。

必要なの

  • Node.js
  • npm
  • gulp
    • gulp-scale-images
    • flat-map
    • gulp-webp

手順

Node.jsとnpmのインストール方法は省略

gulp関連のインストール

1
npm install gulp@4.0.2 gulp-webp@4.0.1 flat-map gulp-scale-images --save-dev

gulp-webp 5.x 以降はこの記事のスクリプトではうごきません
gulp 5.x 以降はこの記事のスクリプトではうごきません

下記スクリプトを gulpfile.js としてプロジェクトのルートに配置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
const path = require('path')
const gulp = require('gulp');
const webp = require('gulp-webp');
const scaleImages = require('gulp-scale-images')
const flatMap = require('flat-map').default

const webpPerFile = (file, cb) =>{
const webpFile = file.clone()
webpFile.scale = {maxWidth:1536, maxHeight:1536,format: 'webp',fit: 'inside'} // 大きさ定義。fitは変更しないことを推奨
cb(null,[webpFile])
}

const computeFileName = (output, scale, cb) => {
const fileName = [
path.basename(output.path, output.extname),
scale.format || output.extname
].join('.')
cb(null, fileName)
}

function weboptimize () {
return gulp.src('source/**/*.{jpg,jpeg,png}') // インプットパス
.pipe(webp())
.pipe(flatMap(webpPerFile))
.pipe(scaleImages(computeFileName))
.pipe(gulp.dest('source/')) // アウトプットパス
};

exports.webp = weboptimize

以下のコマンドを実行することでアウトプットする場所に小さくされたwebpが出力される

1
npx gulp webp

おまけ Hexoのmarkdown内の画像リンクをwebpに変換する

gulp-replaceをインストールする

1
npm install --save-dev gulp-replace

下記スクリプトをgulpfile.jsに追記とか保存とかする

1
2
3
4
5
6
7
8
9
10
11
const gulp = require('gulp');
const replace = require('gulp-replace');

function pnglinkweb (){
return gulp.src('source/**/*.md') //インプットパス
.pipe( replace(/(?<=\!\[.*\]*)(png|jpeg|jpg)/g,'webp') )
.pipe( replace(/(?<=cover.*)(png|jpeg|jpg)/g,'webp') ) // HexoのCoverイメージリンク変換なのでいい感じに改変してください。
.pipe(gulp.dest('source/')) // アウトプットパス
}

exports.webpreplace = pnglinkweb

以下のコマンドを実行することでmarkdownの画像リンクの拡張子がwebpになる

1
npx gulp webpreplace

まとめ

インストール

1
npm install --save-dev gulp gulp-webp flat-map gulp-scale-images gulp-replace

スクリプト

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
const path = require('path')
const gulp = require('gulp');
const webp = require('gulp-webp');
const scaleImages = require('gulp-scale-images')
const flatMap = require('flat-map').default
const replace = require('gulp-replace');

const webpPerFile = (file, cb) =>{
const webpFile = file.clone()
webpFile.scale = {maxWidth:1536, maxHeight:1536,format: 'webp',fit: 'inside'}
cb(null,[webpFile])
}

const computeFileName = (output, scale, cb) => {
const fileName = [
path.basename(output.path, output.extname),
scale.format || output.extname
].join('.')
cb(null, fileName)
}

function weboptimize () {
return gulp.src('source/**/*.{jpg,jpeg,png}')
.pipe(webp())
.pipe(flatMap(webpPerFile))
.pipe(scaleImages(computeFileName))
.pipe(gulp.dest('source/'))
};

function pnglinkweb (){
return gulp.src('source/**/*.md')
.pipe( replace(/(?<=\!\[.*\]*)(png|jpeg|jpg)/g,'webp') )
.pipe( replace(/(?<=cover.*)(png|jpeg|jpg)/g,'webp') ) // HexoのCoverイメージリンク変換なのでいい感じに改変してください。
.pipe(gulp.dest('source/'))
}

exports.webp = weboptimize
exports.webpreplace = pnglinkweb

コマンド

1
2
npx gulp webpreplace
npx gulp webp

参考にしたサイト