これからはじめるGulp #16:gulp-image-resizeプラグインを使ってサムネイルやレスポンシブイメージを作る
はじめに
前回のこれからはじめる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
これで、PhotoshopやWebツールに頼らずともサムネイル画像や画像のリサイズ、軽量化を行えるようになりました。明日はSketch 3との連携について紹介していきたいと思います。
この記事はこれからはじめるGulp(16):gulp-image-resizeプラグインを使ってサムネイルやレスポンシブイメージを作るの転載です。