これからはじめる Gulp シリーズこれからはじめるGulp(16):gulp-image-resizeプラグインを使ってサムネイルやレスポンシブイメージを作る
はじめに
この記事はGulp.js(全俺) Advent Calendar 2014です。
前回のこれからはじめるGulp(15):gulp-responsiveプラグインを使ったレスポンシブイメージ作成の自動化でNode.js向け画像処理ライブラリを使ったレスポンシブイメージ作成の自動化を行いました。今回はより手軽に使えるgulp-image-resizeプラグインを使いサムネイル画像を作ってみたいと思います。
gulp-image-resizeについて
gulp-image-resizeは画像のリサイズや切り抜きができるプラグインです。gulp-image-resizeを使うにはImageMagickかGraphicsMagickが必要です。
ImageMagick or GraphicsMagickのインストール
どちらもHomebrewを使ってインストールします。どちらか一方でかまいませんが、ImageMagickを使うにはオプション指定が必要になります。今回はオプションの指定方法も説明するのであえてImageMagickを使います。
ImageMagickのインストール方法
今回はこちらをインストールします。
$ brew install imagemagick
Graphicsmagickのインストール方法
$ brew install graphicsmagick
gulp-image-resizeのインストール
続いて、gulp-image-resizeプラグイン本体をインストールします。
$ sudo npm install --save-dev gulp-image-resize
Password:
gulp-image-resize@0.5.0 node_modules/gulp-image-resize
├── async@0.2.10
├── through2@0.4.2 (xtend@2.1.2, readable-stream@1.0.33)
├── lodash@2.4.1
├── gulp-gm@0.0.7 (gm@1.17.0)
└── gulp-util@2.2.20 (lodash._reinterpolate@2.4.1, minimist@0.2.0, vinyl@0.2.3, chalk@0.5.1, through2@0.5.1, multipipe@0.1.2, dateformat@1.0.11, lodash.template@2.4.1)
サムネイルを作成するタスク
141枚のスクリーンキャプチャを用意し、サムネイル画像を作ってみます。まずは横200px:縦200pxの画像の中心を基準にしたサムネイルを作成し、gulp-imageminプラグインと連携して軽量化するタスクを作ります。このタスクにはgulp-changedプラグインとと処理されたファイル名をログに流すgulp-filelogプラグインを使います。gulp-filelogを使うことでタスクの進捗を把握します。
var gulp = require('gulp');
var changed = require('gulp-changed');
var filelog = require('gulp-filelog');
var imageResize = require('gulp-image-resize');
var imagemin = require('gulp-imagemin');
var paths = {
srcDir : 'src',
prvDir : 'prv',
dstDir : 'prd',
uploadsDir: '/uploads'
}
gulp.task( 'image-optim:thumb', function(){
var baseDir = paths.srcDir + paths.uploadsDir + '/origin';
var srcGlob = paths.srcDir + paths.uploadsDir + '/origin/**/*.+(jpg|jpeg|png|gif)';
var dstGlob = paths.dstDir + paths.uploadsDir + '/thumb';
var resizeOptions = {
width : 200,
height : 200,
gravity : 'Center',
crop : true,
upscale : false,
imageMagick : true
};
var imageminOptions = {
optimizationLevel: 7
};
return gulp.src( srcGlob, { base: baseDir } )
.pipe(changed( dstGlob ))
.pipe(imageResize( resizeOptions ))
.pipe(imagemin( imageminOptions ))
.pipe(gulp.dest( dstGlob ))
.pipe(filelog());
});
リサイズオプションの指定はこのようになります。imageMagick : true
がImageMagickを使うための指定です。
var resizeOptions = {
width : 200,
height : 200,
gravity : 'Center',
crop : true,
upscale : false,
imageMagick : true
};
image-optim:thumbタスクの実行
タスクを実行してみます(長すぎるので途中を省いています)。
$ gulp image-optim:thumb
[00:00:04] Using gulpfile ~/Projects/gulp.whiskers.nukos.kitchen/gulpfile.js
[00:00:04] Starting 'image-optim:thumb'...
[00:00:05] [1] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/08/gifbrewery/animation_gif.gif]
[00:00:06] [2] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/08/gifbrewery/capture_tool.png]
[00:00:08] [3] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/08/gr/gr_photo_001.jpg]
[00:00:08] [4] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/08/gr/gr_photo_002.jpg]
[00:00:09] [5] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/08/gifbrewery/crop.png]
[00:00:10] [6] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/08/gifbrewery/open_gifbrewery.png]
[00:00:10] [7] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/08/gifbrewery/gif_animation.png]
[00:00:10] [8] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/06/start/thumbnail_960.png]
[00:00:11] [9] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/09/monotony/kimonolabs.png]
…
[00:01:45] gulp-imagemin: Minified 141 images (saved 647.91 kB - 22%)
[00:01:45] [141] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/11/high-performance-browser-networking-meetup/thumbnail.png]
[00:01:45] Found [141] files.
[00:01:45] Finished 'image-optim:thumb' after 1.68 min
141個のサムネイル作成に1分45秒かかり、22%軽量化できました。[/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb/2014/09/monotony/kimonolabs.png]
がgulp-filelogが出力したログです。もう一度タスクを実行するとgulp-chagedが効き処理が省略されます。
$ gulp image-optim:thumb
[02:52:40] Using gulpfile ~/Projects/gulp.whiskers.nukos.kitchen/gulpfile.js
[02:52:40] Starting 'image-optim:thumb'...
[02:52:41] gulp-imagemin: Minified 0 images (saved 0 B - 0%)
[02:52:41] Found [0] files.
[02:52:41] Finished 'image-optim:thumb' after 318 ms
高解像度ディスプレイ用のサムネイルとミドルサイズの画像を作る
追加で2種類の画像とオリジナル画像を軽量化するタスクを作ります。この3種類タスクは管理しやすくするため別々のタスクとします。
400*400のサムネイルを作るタスク
//create thumb 2x size
gulp.task( 'image-optim:thumb-2x', function(){
var baseDir = paths.srcDir + paths.uploadsDir + '/origin';
var srcGlob = paths.srcDir + paths.uploadsDir + '/origin/**/*.+(jpg|jpeg|png|gif)';
var dstGlob = paths.dstDir + paths.uploadsDir + '/thumb-2x';
var resizeOptions = {
width : 400,
height : 400,
gravity : 'Center',
crop : true,
upscale : false,
imageMagick : true
};
var imageminOptions = {
optimizationLevel: 7
};
return gulp.src( srcGlob, { base: baseDir } )
.pipe(changed( dstGlob ))
.pipe(imageResize( resizeOptions ))
.pipe(imagemin( imageminOptions ))
.pipe(gulp.dest( dstGlob ))
.pipe(filelog());
});
ミドルサイズの画像を作るタスク
//create middle size
gulp.task( 'image-optim:middle', function(){
var baseDir = paths.srcDir + paths.uploadsDir + '/origin';
var srcGlob = paths.srcDir + paths.uploadsDir + '/origin/**/*.+(jpg|jpeg|png|gif)';
var dstGlob = paths.dstDir + paths.uploadsDir + '/middle';
var resizeOptions = {
width : 960,
upscale : false,
imageMagick : true
};
var imageminOptions = {
optimizationLevel: 7
};
return gulp.src( srcGlob, { base: baseDir } )
.pipe(changed( dstGlob ))
.pipe(imageResize( resizeOptions ))
.pipe(imagemin( imageminOptions ))
.pipe(gulp.dest( dstGlob ))
.pipe(filelog());
});
オリジナル画像を軽量化するタスク
//optimize origin
gulp.task( 'image-optim:origin', function(){
var baseDir = paths.srcDir + paths.uploadsDir + '/origin';
var srcGlob = paths.srcDir + paths.uploadsDir + '/origin/**/*.+(jpg|jpeg|png|gif|svg)';
var dstGlob = paths.dstDir + paths.uploadsDir + '/origin';
var imageminOptions = {
optimizationLevel: 7
};
return gulp.src( srcGlob, { base: baseDir } )
.pipe(changed( dstGlob ))
.pipe(imagemin( imageminOptions ))
.pipe(gulp.dest( dstGlob ))
.pipe(filelog());
});
それぞれのタスクを非同期処理させるようimage-optim
というタスクを作ります。
gulp.task( 'image-optim', ['image-optim:thumb', 'image-optim:thumb-2x', 'image-optim:middle', 'image-optim:origin']);
image-optimタスクを実行する
image-optimタスクですべての画像処理を実行します。4つのタスクが非同期で処理されます。
$ gulp image-optim
[02:57:08] Using gulpfile ~/Projects/gulp.whiskers.nukos.kitchen/gulpfile.js
[02:57:08] Starting 'image-optim:thumb'...
[02:57:08] Starting 'image-optim:thumb-2x'...
[02:57:08] Starting 'image-optim:middle'...
[02:57:08] Starting 'image-optim:origin'...
[02:57:09] gulp-imagemin: Minified 0 images (saved 0 B - 0%)
[02:57:09] Found [0] files.
[02:57:09] Finished 'image-optim:thumb' after 1.06 s
[02:57:09] [1] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/origin/2014/08/gifbrewery/animation_gif.gif]
[02:57:10] [1] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/middle/2014/08/gifbrewery/animation_gif.gif]
[02:57:10] [1] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb-2x/2014/08/gifbrewery/animation_gif.gif]
[02:57:15] [2] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb-2x/2014/06/start/thumbnail_960.png]
[02:57:49] [2] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/origin/2014/06/start/thumbnail_960.png]
[02:57:50] [2] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/middle/2014/06/start/thumbnail_960.png]
[02:57:54] [3] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/thumb-2x/2014/08/gifbrewery/capture_tool.png]
...
[03:25:40] gulp-imagemin: Minified 141 images (saved 2.29 MB - 12.2%)
[03:25:40] [141] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/middle/2014/11/high-performance-browser-networking-meetup/thumbnail.png]
[03:25:40] Found [141] files.
[03:25:40] Finished 'image-optim:middle' after 29 min
[03:25:40] [136] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/origin/2014/11/ios_byword_and_ver22/iphone_preview.png]
[03:25:42] [137] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/origin/2014/11/ios_byword_and_ver22/upload_success.png]
[03:26:19] [138] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/origin/2014/10/hello-yosemite/vmware_error.png]
[03:26:50] [139] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/origin/2014/10/hello-yosemite/thumbnail.png]
[03:27:03] [140] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/origin/2014/11/high-performance-browser-networking-meetup/thumbnail.png]
[03:27:28] gulp-imagemin: Minified 141 images (saved 11.44 MB - 34.9%)
[03:27:28] [141] [/Users/ryuichi/Projects/gulp.whiskers.nukos.kitchen/prd/uploads/origin/2014/11/ios_byword_and_ver22/ipad_preview.png]
[03:27:28] Found [141] files.
[03:27:28] Finished 'image-optim:origin' after 30 min
[03:27:28] Starting 'image-optim'...
[03:27:28] Finished 'image-optim' after 27 μs
すべてのタスクが完了するまで30分程度かかりました。オリジナルの画像が2000px以上の画像だったりするのでやはり時間がかかりました。初回はファイル量が多いため時間がかかってしまうのも仕方ありませんが、2回目以降は変更しれたファイルのみが対象となるためそれほど気にならなくなります。もう一度実行してみるとgulp-changedプラグインのおかげで一切の処理が実行されていません。
$ gulp image-optim
[03:35:07] Using gulpfile ~/Projects/gulp.whiskers.nukos.kitchen/gulpfile.js
[03:35:07] Starting 'image-optim:thumb'...
[03:35:07] Starting 'image-optim:thumb-2x'...
[03:35:07] Starting 'image-optim:middle'...
[03:35:07] Starting 'image-optim:origin'...
[03:35:07] gulp-imagemin: Minified 0 images (saved 0 B - 0%)
[03:35:07] Found [0] files.
[03:35:07] Finished 'image-optim:origin' after 375 ms
[03:35:07] gulp-imagemin: Minified 0 images (saved 0 B - 0%)
[03:35:07] Found [0] files.
[03:35:07] Finished 'image-optim:thumb-2x' after 383 ms
[03:35:07] gulp-imagemin: Minified 0 images (saved 0 B - 0%)
[03:35:07] Found [0] files.
[03:35:07] Finished 'image-optim:thumb' after 396 ms
[03:35:07] gulp-imagemin: Minified 0 images (saved 0 B - 0%)
[03:35:07] Found [0] files.
[03:35:07] Finished 'image-optim:middle' after 381 ms
[03:35:07] Starting 'image-optim'...
[03:35:07] Finished 'image-optim' after 8 μs
これで、ドローツールに頼らずともサムネイル画像や画像のリサイズを行えるようになりました。明日からSketch 3との連携について紹介していきたいと思います。
シリーズ
- これからはじめるGulp(0):アドベントカレンダースケジュール
- これからはじめるGulp(1):bundler, rbenv, nodebrewでGulp環境を作ってみる
- これからはじめるGulp(2):gulp-sassを使ってSCSSをコンパイルするタスクを作ってみる
- これからはじめるGulp(3):gulp.watchでファイルの変更を監視しタスクを実行する
- これからはじめるGulp(4):gulp-connectモジュールを使ったローカルサーバの起動
- これからはじめるGulp(5):gulp-connectモジュールを使ったLiveReload
- これからはじめるGulp(6):gulp-plumberとgulp-notifyを使ったデスクトップ通知
- これからはじめるGulp(7):require-dirモジュールを使ったタスク単位のファイル分割
- これからはじめるGulp(8):delモジュールとvinyl-pathsモジュールを使ったファイルの削除
- これからはじめるGulp(9):Ruby版Sassが使えるgulp-ruby-sassへの乗り換え
- これからはじめるGulp(10):deprecatedになっていたgulp-connectからgulp-webserverへ乗り換える
- これからはじめるGulp(11):ブラウザ間でスクロールやクリック操作を同期できるBrowserSync
- これからはじめるGulp(12):gulp-imageminプラグインを使ったJPEG,PNG,GIF,SVGの最適化
- これからはじめるGulp(13):gulp-changedプラグインで変更されたファイルだけを処理させる
- これからはじめるGulp(14):gulp-cachedプラグインで変更されたSCSSファイルだけを処理させる
- これからはじめるGulp(15):gulp-responsiveプラグインを使ったレスポンシブイメージ作成の自動化
- これからはじめるGulp(16):gulp-image-resizeプラグインを使ってサムネイルやレスポンシブイメージを作る
- これからはじめるGulp(17):SketchTool(Sketch 3 command line tool)を使ったアートボード・スライスの書き出しとgulp-execプラグインを使ったSketchtoolの呼び出し
- これからはじめるGulp(18):SketchToolで何ができるのかコマンドと主要なオプションを使ってみる
- これからはじめるGulp(19):gulp-sketchとgulp-execを使ったSketch 3デザインデータの画像書き出し
- これからはじめるGulp(20):Node.jsのChild Processモジュールを使ってgulpからjekyllのbuildコマンドを実行する
- これからはじめるGulp(21):gulp-awspublishプラグインを使ったAmazon S3への静的Webサイトパブリッシュ
- これからはじめるGulp(22):gulp-iconfontとgulp-sketchを使ったアイコンフォント作成の自動化
- これからはじめるGulp(23):gulp-consolidateでgulp-iconfontで作ったアイコンフォントのシンボル一覧HTMLを作る
- これからはじめるGulp(24):gulp.spritesmithプラグインでSpriteイメージを作る
- これからはじめるGulp(25):Hologramとgulp-hologramでスタイルガイドを作る
- これからはじめるGulp(26):Sketch3のサブディレクトリ書き出しに対応したgulp-sketchを試す