├── .editorconfig ├── .gitignore ├── .jshintrc ├── .travis.yml ├── README.md ├── gulpfile.js ├── index.js ├── package.json └── test ├── expected ├── convert │ └── wikipedia.jpg ├── cover │ ├── Rhododendron.jpg │ └── TeslaTurbine.png ├── crop │ └── wikipedia.png ├── crop_gravity │ └── wikipedia.png ├── crop_width_only │ └── wikipedia.png ├── filter │ └── Rhododendron.jpg ├── flatten │ └── wikipedia.jpg ├── interlace │ ├── Rhododendron.jpg │ └── wikipedia.png ├── interlace_and_resize │ ├── Rhododendron.jpg │ └── wikipedia.png ├── no_upscale │ └── wikipedia.png ├── no_upscale2 │ └── wikipedia.png ├── percentage │ ├── Rhododendron.jpg │ ├── TeslaTurbine.png │ ├── gnu.jpg │ ├── hamburg.jpg │ └── wikipedia.png ├── quality │ └── Rhododendron.jpg ├── resize │ ├── Rhododendron.jpg │ ├── TeslaTurbine.png │ ├── gnu.jpg │ └── wikipedia.png ├── samplingFactor │ └── Rhododendron.jpg ├── sharpen │ └── Rhododendron.jpg ├── upscale │ └── wikipedia.png └── upscale2 │ └── wikipedia.png ├── fixtures ├── Rhododendron.jpg ├── TeslaTurbine.png ├── gnu.jpg ├── hamburg.jpg └── wikipedia.png └── image_resize_test.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | root = true 3 | 4 | [*] 5 | indent_style = space 6 | indent_size = 2 7 | end_of_line = lf 8 | charset = utf-8 9 | trim_trailing_whitespace = true 10 | insert_final_newline = true 11 | 12 | [*.md] 13 | trim_trailing_whitespace = false -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | npm-debug.log 3 | tmp 4 | .DS_Store 5 | -------------------------------------------------------------------------------- /.jshintrc: -------------------------------------------------------------------------------- 1 | { 2 | "curly": true, 3 | "eqeqeq": true, 4 | "immed": true, 5 | "latedef": true, 6 | "newcap": true, 7 | "noarg": true, 8 | "sub": true, 9 | "undef": true, 10 | "boss": true, 11 | "eqnull": true, 12 | "node": true, 13 | "esnext": true 14 | } 15 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | --- 2 | language: node_js 3 | 4 | node_js: 5 | - "node" 6 | 7 | before_install: 8 | - npm install -g gulp 9 | - sudo apt-get install graphicsmagick 10 | 11 | install: 12 | - npm install 13 | 14 | os: 15 | #- osx 16 | - linux 17 | 18 | script: npm test 19 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # [gulp](https://github.com/wearefractal/gulp)-image-resize [![Build Status](https://api.travis-ci.org/scalableminds/gulp-image-resize.svg?branch=master)](https://travis-ci.org/scalableminds/gulp-image-resize) 2 | 3 | 4 | > Resizing images made easy - thanks to [GraphicsMagick](http://www.graphicsmagick.org/) or [ImageMagick](http://www.imagemagick.org/). 5 | > Fork of [grunt-image-resize](https://github.com/excellenteasy/grunt-image-resize). 6 | 7 | ## Install 8 | 9 | Install with [npm](https://npmjs.org/package/gulp-image-resize) 10 | 11 | ``` 12 | npm install --save-dev gulp-image-resize 13 | ``` 14 | 15 | ### GraphicsMagick or ImageMagick 16 | Make sure GraphicsMagick or ImageMagick is installed on your system and properly set up in your `PATH`. 17 | 18 | Ubuntu: 19 | 20 | ```shell 21 | apt-get install imagemagick 22 | apt-get install graphicsmagick 23 | ``` 24 | 25 | Mac OS X (using [Homebrew](http://brew.sh/)): 26 | 27 | ```shell 28 | brew install imagemagick 29 | brew install graphicsmagick 30 | ``` 31 | 32 | Windows & others: 33 | 34 | [http://www.imagemagick.org/script/binary-releases.php](http://www.imagemagick.org/script/binary-releases.php) 35 | 36 | Confirm that ImageMagick is properly set up by executing `convert -help` in a terminal. 37 | 38 | 39 | ## Example 40 | 41 | ```js 42 | const gulp = require('gulp'); 43 | const imageResize = require('gulp-image-resize'); 44 | 45 | gulp.task('default', () => 46 | gulp 47 | .src('test.png') 48 | .pipe(imageResize({ 49 | width : 100, 50 | height : 100, 51 | crop : true, 52 | upscale : false 53 | })) 54 | .pipe(gulp.dest('dist'))); 55 | ``` 56 | 57 | ## API 58 | 59 | ### imageResize(options) 60 | 61 | #### options.width 62 | 63 | Type: `Number` 64 | Default value: `0` (only if height is defined) 65 | 66 | A number value that is passed as pixel or percentage value to imagemagick. 67 | 68 | 69 | #### options.height 70 | 71 | Type: `Number` 72 | Default value: `0` (only if width is defined) 73 | 74 | A number value that is passed as pixel or percentage value to imagemagick. 75 | 76 | 77 | #### options.upscale 78 | 79 | Type: `Boolean` 80 | Default value: `false` 81 | 82 | Determines whether images will be upscaled. If set to `false` (default), image will be copied instead of resized if it would be upscaled by resizing. 83 | 84 | 85 | #### options.crop 86 | 87 | Type: `Boolean` 88 | Default value: `false` 89 | 90 | Determines whether images will be cropped after resizing to exactly match `options.width` and `options.height`. 91 | 92 | 93 | #### options.gravity 94 | 95 | Type: `String` 96 | Default value: `Center` 97 | Possible values: `NorthWest`, `North`, `NorthEast`, `West`, `Center`, `East`, `SouthWest`, `South`, `SouthEast` 98 | 99 | When cropping images this sets the image gravity. Doesn't have any effect, if `options.crop` is `false`. 100 | 101 | 102 | #### options.quality 103 | 104 | Type: `Number` 105 | Default value: `1` 106 | 107 | Determines the output quality of the resized image. Ranges from `0` (really bad) to `1` (almost lossless). Only applies to jpg images. 108 | 109 | 110 | #### options.format 111 | 112 | Type: `String` 113 | Default value: Format of the input file 114 | Possible values: `gif`, `png`, `jpeg` etc. 115 | 116 | Override the output format of the processed file. 117 | 118 | #### options.filter 119 | 120 | Type: `String` 121 | Possible values: `Point`, `Box`, `Triangle`, `Hermite`, `Hanning`, `Hamming`, `Blackman`, `Gaussian`, `Quadratic`, `Cubic`, `Catrom`, `Mitchell`, `Lanczos`, `Bessel`, `Sinc` 122 | 123 | Set the filter to use when resizing (e.g. Catrom is very good for reduction, while hermite is good for enlargement). 124 | 125 | #### options.sharpen 126 | 127 | Type: `Boolean | String` 128 | Default value: `false` 129 | 130 | Set to `true` to apply a slight unsharp mask after resizing. 131 | Or set a string to setup the unsharp. See [gm unsharp documentation](http://www.graphicsmagick.org/GraphicsMagick.html#details-unsharp). (e.g. '0.5x0.5+0.5+0.008') 132 | 133 | #### options.samplingFactor 134 | 135 | Type: `Array[Cr, Cb]` 136 | Possible values: `[2, 2]` for 4:2:2, `[1, 1]` for 4:1:1 137 | 138 | Define chroma subsampling 139 | 140 | #### options.noProfile 141 | 142 | Type: `Boolean` 143 | Default value: `false` 144 | 145 | Set to `true` to enforce removal of all embedded profile data like icc, exif, iptc, xmp 146 | and so on. If source files represent e.g. untouched camera data or images optimized for 147 | print this may decrease image size drastically. Therefore this is probably wanted in 148 | cases where thumbnails are generated for web preview purposes. For details look for parameter _+profile "*"_ in the [gm profile documentation](http://www.graphicsmagick.org/GraphicsMagick.html#details-profile). 149 | 150 | #### options.interlace 151 | 152 | Type: `Boolean` 153 | Default value: `false` 154 | 155 | Set to `true` to create interlaced images (scanline interlacing) from PNG, GIF or JPEG files 156 | (also known as "progressive" JPEG). For details look for parameter _-interlace <type>_ with the type value set to 157 | "Line" in the [gm profile documentation](http://www.graphicsmagick.org/GraphicsMagick.html#details-interlace). 158 | 159 | #### options.imageMagick 160 | 161 | Type: `Boolean` 162 | Default value: `false` 163 | 164 | Set to `true` when using ImageMagick instead of GraphicsMagick. 165 | 166 | #### options.background 167 | 168 | Type: `String` 169 | Possible values: `none` to keep transparency, `beige` to set beige background, `#888` for gray. 170 | 171 | Define background color (default is white), for example when converting SVG images to PNGs. 172 | See [gm background documentation](http://www.graphicsmagick.org/GraphicsMagick.html#details-background) 173 | 174 | #### options.flatten 175 | 176 | Type: `Boolean` 177 | Default value: `false` 178 | 179 | Combines image layers into one. Can be used for layered formats such as PNG. See [gm flatten documentation](http://www.graphicsmagick.org/GraphicsMagick.html#details-flatten). 180 | 181 | #### options.percentage 182 | 183 | Type: `Number` 184 | Default value: `null` 185 | 186 | The value that you want the image to be scaled to. 187 | 188 | 189 | #### options.cover 190 | 191 | Type: `Boolean` 192 | Default value: `false` 193 | 194 | Determines whether images should cover the area specified by the width and height options. If set to `true`, the resized images will maintain aspect ratio by overflowing their dimensions as necessary, rather than treating them as maximum-size constraints. 195 | 196 | 197 | ## More Examples 198 | 199 | ```js 200 | // Converting from png to jpeg. No resizing. 201 | gulp.task('convert_png', () => 202 | gulp 203 | .src('test.png') 204 | .pipe(imageResize({ 205 | format : 'jpeg' 206 | })) 207 | .pipe(gulp.dest('dist'))); 208 | 209 | // Only specify one dimension. Output image won't exceed this value. 210 | gulp.task('width', () => 211 | gulp 212 | .src('test.png') 213 | .pipe(imageResize({ 214 | width : 100 215 | })) 216 | .pipe(gulp.dest('dist'))); 217 | 218 | // Convert with percentage value. 219 | gulp.task('percentage', () => 220 | gulp 221 | .src('test.png') 222 | .pipe(imageResize({ 223 | percentage: 50 224 | })) 225 | .pipe(gulp.dest('dist'))); 226 | ``` 227 | 228 | ## Recommended modules 229 | 230 | * [concurrent-transform](https://github.com/segmentio/concurrent-transform): parallelize image resizing 231 | ```js 232 | const parallel = require("concurrent-transform"); 233 | const os = require("os"); 234 | 235 | gulp.task("parallel", () => 236 | gulp 237 | .src("src/**/*.{jpg,png}") 238 | .pipe(parallel( 239 | imageResize({ 240 | width : 100 241 | }), 242 | os.cpus().length 243 | )) 244 | .pipe(gulp.dest("dist"))); 245 | ``` 246 | 247 | * [gulp-changed](https://www.npmjs.org/package/gulp-changed/): only resize changed images 248 | ```js 249 | const changed = require("gulp-changed"); 250 | 251 | gulp.task("changed", () => 252 | gulp 253 | .src("src/**/*.{jpg,png}") 254 | .pipe(changed("dist")) 255 | .pipe(imageResize({ 256 | width : 100 257 | })) 258 | .pipe(gulp.dest("dist"))); 259 | ``` 260 | 261 | * [gulp-rename](https://www.npmjs.org/package/gulp-rename/): add a suffix or prefix 262 | ```js 263 | const rename = require("gulp-rename"); 264 | 265 | gulp.task("suffix", () => 266 | gulp 267 | .src("src/**/*.{jpg,png}") 268 | .pipe(imageResize({ 269 | width : 100 270 | })) 271 | .pipe(rename(function (path) { 272 | path.basename += "-thumbnail"; 273 | })) 274 | .pipe(gulp.dest("dist"))); 275 | ``` 276 | 277 | ## Tests 278 | 279 | 1. You need both ImageMagick and GraphicsMagick installed on your system to run the tests. 280 | 2. Install all npm dev dependencies `npm install` 281 | 3. Install gulp globally `npm install -g gulp` 282 | 4. Run `gulp test` 283 | 284 | 285 | ## License 286 | 287 | MIT © [scalable minds](http://scm.io) 288 | -------------------------------------------------------------------------------- /gulpfile.js: -------------------------------------------------------------------------------- 1 | var gulp = require("gulp"); 2 | var mocha = require("gulp-mocha"); 3 | var clean = require("gulp-clean"); 4 | var jshint = require("gulp-jshint"); 5 | var stylish = require("jshint-stylish"); 6 | var sequence = require("run-sequence"); 7 | 8 | var imageResize = require("./index.js"); 9 | 10 | 11 | 12 | gulp.task("jshint", function () { 13 | gulp.src(["gulpfile.js", "index.js", "test/*.js"]) 14 | .pipe(jshint()) 15 | .pipe(jshint.reporter(stylish)); 16 | }); 17 | 18 | gulp.task("clean", function () { 19 | gulp.src("tmp/*", { read : false }) 20 | .pipe(clean()); 21 | }); 22 | 23 | gulp.task("mocha", ["image_resize"], function () { 24 | return gulp.src("test/*_test.js") 25 | .pipe(mocha({ reporter: "spec" })); 26 | }); 27 | 28 | 29 | 30 | var resizeTasks = []; 31 | 32 | var resize = function(files, key, options) { 33 | 34 | function makeTask(files, key, options) { 35 | gulp.task("image_resize:" + key, function () { 36 | return gulp.src(files) 37 | .pipe(imageResize(options)) 38 | .pipe(gulp.dest("tmp/" + key)); 39 | }); 40 | resizeTasks.push("image_resize:" + key); 41 | } 42 | 43 | makeTask(files, key, options); 44 | 45 | var imOptions = { imageMagick : true }; 46 | for (var k in options) { imOptions[k] = options[k]; } 47 | makeTask(files, key + "_imagemagick", imOptions); 48 | }; 49 | 50 | 51 | resize([ 52 | "test/fixtures/gnu.jpg", 53 | "test/fixtures/wikipedia.png", 54 | "test/fixtures/Rhododendron.jpg", 55 | "test/fixtures/TeslaTurbine.png" 56 | ], "resize", { 57 | width: 100 58 | }); 59 | 60 | 61 | resize("test/fixtures/wikipedia.png", "upscale", { 62 | width: 600, 63 | height: 0, 64 | upscale: true 65 | }); 66 | 67 | resize("test/fixtures/wikipedia.png", "upscale2", { 68 | width: 600, 69 | height: 600, 70 | upscale: true 71 | }); 72 | 73 | resize("test/fixtures/wikipedia.png", "no_upscale", { 74 | width: 600, 75 | upscale: false 76 | }); 77 | 78 | resize("test/fixtures/wikipedia.png", "no_upscale2", { 79 | width: 100, 80 | height: 600, 81 | upscale: false 82 | }); 83 | 84 | resize("test/fixtures/wikipedia.png", "crop", { 85 | width: 400, 86 | height: 300, 87 | upscale: false, 88 | crop: true 89 | }); 90 | 91 | resize("test/fixtures/wikipedia.png", "crop_gravity", { 92 | width: 400, 93 | height: 300, 94 | upscale: false, 95 | crop: true, 96 | gravity: "NorthWest" 97 | }); 98 | 99 | resize("test/fixtures/wikipedia.png", "crop_width_only", { 100 | width: 300, 101 | crop: true 102 | }); 103 | 104 | resize("test/fixtures/Rhododendron.jpg", "quality", { 105 | width: 600, 106 | height: 0, 107 | upscale: false, 108 | quality: 0.2 109 | }); 110 | 111 | resize("test/fixtures/Rhododendron.jpg", "sharpen", { 112 | width: 600, 113 | height: 0, 114 | sharpen: true 115 | }); 116 | 117 | resize("test/fixtures/Rhododendron.jpg", "filter", { 118 | width: 600, 119 | height: 0, 120 | filter: "catrom" 121 | }); 122 | 123 | resize("test/fixtures/Rhododendron.jpg", "samplingFactor", { 124 | width: 600, 125 | height: 0, 126 | samplingFactor: [2,2] 127 | }); 128 | 129 | resize("test/fixtures/wikipedia.png", "convert", { 130 | format: "jpg" 131 | }); 132 | 133 | resize("test/fixtures/hamburg.jpg", "noProfile", { 134 | noProfile: true 135 | }); 136 | 137 | resize("test/fixtures/wikipedia.png", "flatten", { 138 | format: "jpg", 139 | flatten: true 140 | }); 141 | 142 | resize([ 143 | "test/fixtures/Rhododendron.jpg", 144 | "test/fixtures/wikipedia.png" 145 | ], "interlace", { 146 | interlace: true 147 | }); 148 | 149 | resize([ 150 | "test/fixtures/Rhododendron.jpg", 151 | "test/fixtures/wikipedia.png" 152 | ], "interlace_and_resize", { 153 | width: 400, 154 | interlace: true 155 | }); 156 | 157 | resize([ 158 | "test/fixtures/gnu.jpg", 159 | "test/fixtures/wikipedia.png", 160 | "test/fixtures/Rhododendron.jpg", 161 | "test/fixtures/TeslaTurbine.png" 162 | ], "percentage", { 163 | percentage: 50 164 | }); 165 | 166 | resize([ 167 | "test/fixtures/Rhododendron.jpg", 168 | "test/fixtures/TeslaTurbine.png" 169 | ], "cover", { 170 | width: 200, 171 | height: 200, 172 | cover: true 173 | }); 174 | 175 | gulp.task("image_resize", resizeTasks); 176 | 177 | gulp.task("test", function(callback) { 178 | sequence("clean", "jshint", "mocha", callback); 179 | }); 180 | 181 | gulp.task("default", ["test"]); 182 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | /* 2 | * grunt-image-resize 3 | * https://github.com/scalableminds/gulp-image-resize 4 | * 5 | * Copyright (c) 2014 Norman Rzepka 6 | * Licensed under the MIT license. 7 | */ 8 | 9 | var gm = require("gulp-gm"); 10 | var async = require("async"); 11 | var _ = require("lodash"); 12 | 13 | module.exports = function imageResizer(_options) { 14 | 15 | _options = _.defaults(_options, { 16 | overwrite : true, 17 | upscale : false, 18 | crop : false, 19 | gravity : "Center", 20 | quality : 1, 21 | noProfile : false, 22 | sharpen : false, 23 | imageMagick : false, 24 | format : null, 25 | flatten : false, 26 | interlace : false, 27 | percentage : null, 28 | cover : false 29 | }); 30 | 31 | return gm(function(gmfile, done) { 32 | 33 | async.waterfall([ 34 | 35 | function (callback) { 36 | gmfile.size(callback); 37 | }, 38 | 39 | function (size, callback) { 40 | 41 | var options = JSON.parse(JSON.stringify(_options)); // fix: we must make a copy, because we will change it! 42 | 43 | if (options.filter != null) { 44 | gmfile = gmfile.filter(options.filter); 45 | } 46 | 47 | if (options.height != null || options.width != null) { 48 | 49 | // if upscale is not requested, restrict size 50 | if(!options.upscale){ 51 | if (!isNaN(options.width)) { 52 | options.width = Math.min(options.width, size.width); 53 | } 54 | if (!isNaN(options.height)) { 55 | options.height = Math.min(options.height, size.height); 56 | } 57 | } 58 | 59 | // if one dimension is not set - we fill it proportionally 60 | if (!options.height) { 61 | if (options.crop) { 62 | options.height = size.height; 63 | } else { 64 | options.height = Math.ceil((options.width / size.width) * size.height); 65 | } 66 | } 67 | if (!options.width) { 68 | if (options.crop) { 69 | options.width = size.width; 70 | } else { 71 | options.width = Math.ceil((options.height / size.height) * size.width); 72 | } 73 | } 74 | 75 | if (options.crop) { 76 | gmfile = gmfile 77 | .resize(options.width, options.height, "^") 78 | .gravity(options.gravity) 79 | .crop(options.width, options.height); 80 | } else if (options.cover) { 81 | gmfile = gmfile 82 | .resize(options.width, options.height, "^"); 83 | } else { 84 | gmfile = gmfile 85 | .resize(options.width, options.height); 86 | } 87 | 88 | } else if (options.percentage) { 89 | gmfile = gmfile 90 | .resize(options.percentage, null, '%'); 91 | } 92 | 93 | if (options.format) { 94 | gmfile = gmfile 95 | .setFormat(options.format); 96 | } 97 | 98 | if (options.quality !== 1) { 99 | gmfile = gmfile.quality(Math.floor(options.quality * 100)); 100 | } 101 | 102 | 103 | if (options.samplingFactor != null) { 104 | gmfile = gmfile 105 | .samplingFactor(options.samplingFactor[0], options.samplingFactor[1]); 106 | } 107 | 108 | if (options.sharpen) { 109 | options.sharpen = (typeof options.sharpen === 'string') ? options.sharpen : '1.5x1+0.7+0.02'; 110 | gmfile = gmfile.unsharp(options.sharpen); 111 | } 112 | 113 | if (options.flatten) { 114 | gmfile = gmfile.flatten(); 115 | } 116 | 117 | if (options.interlace) { 118 | gmfile = gmfile.interlace('Line'); 119 | } 120 | 121 | if (options.background) { 122 | gmfile = gmfile.background(options.background); 123 | } 124 | 125 | if (options.noProfile) { 126 | gmfile = gmfile.noProfile(); 127 | } 128 | 129 | callback(null, gmfile); 130 | } 131 | 132 | ], done); 133 | 134 | }, { imageMagick : _options.imageMagick }); 135 | 136 | }; 137 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "gulp-image-resize", 3 | "description": "Resizing images made easy.", 4 | "version": "0.13.1", 5 | "homepage": "https://github.com/scalableminds/gulp-image-resize", 6 | "author": { 7 | "name": "Norman Rzepka", 8 | "email": "norman@scm.io", 9 | "url": "http://scm.io" 10 | }, 11 | "repository": { 12 | "type": "git", 13 | "url": "git://github.com/scalableminds/gulp-image-resize" 14 | }, 15 | "bugs": { 16 | "url": "https://github.com/scalableminds/gulp-image-resize/issues" 17 | }, 18 | "license": "MIT", 19 | "main": "index.js", 20 | "engines": { 21 | "node": ">= 0.10.0" 22 | }, 23 | "scripts": { 24 | "test": "gulp test" 25 | }, 26 | "devDependencies": { 27 | "gulp": "~3.5.5", 28 | "gm": "~1.14.2", 29 | "gulp-clean": "~0.2.4", 30 | "gulp-jshint": "~1.5.0", 31 | "run-sequence": "~0.3.6", 32 | "jshint-stylish": "~0.1.5", 33 | "gulp-mocha": "~0.4.1" 34 | }, 35 | "keywords": [ 36 | "gulpplugin" 37 | ], 38 | "dependencies": { 39 | "async": "~2.6.2", 40 | "gulp-gm": "~0.0.9", 41 | "through2": "~2.0.5", 42 | "lodash": "~4.17.14" 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /test/expected/convert/wikipedia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/convert/wikipedia.jpg -------------------------------------------------------------------------------- /test/expected/cover/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/cover/Rhododendron.jpg -------------------------------------------------------------------------------- /test/expected/cover/TeslaTurbine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/cover/TeslaTurbine.png -------------------------------------------------------------------------------- /test/expected/crop/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/crop/wikipedia.png -------------------------------------------------------------------------------- /test/expected/crop_gravity/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/crop_gravity/wikipedia.png -------------------------------------------------------------------------------- /test/expected/crop_width_only/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/crop_width_only/wikipedia.png -------------------------------------------------------------------------------- /test/expected/filter/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/filter/Rhododendron.jpg -------------------------------------------------------------------------------- /test/expected/flatten/wikipedia.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/flatten/wikipedia.jpg -------------------------------------------------------------------------------- /test/expected/interlace/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/interlace/Rhododendron.jpg -------------------------------------------------------------------------------- /test/expected/interlace/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/interlace/wikipedia.png -------------------------------------------------------------------------------- /test/expected/interlace_and_resize/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/interlace_and_resize/Rhododendron.jpg -------------------------------------------------------------------------------- /test/expected/interlace_and_resize/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/interlace_and_resize/wikipedia.png -------------------------------------------------------------------------------- /test/expected/no_upscale/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/no_upscale/wikipedia.png -------------------------------------------------------------------------------- /test/expected/no_upscale2/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/no_upscale2/wikipedia.png -------------------------------------------------------------------------------- /test/expected/percentage/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/percentage/Rhododendron.jpg -------------------------------------------------------------------------------- /test/expected/percentage/TeslaTurbine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/percentage/TeslaTurbine.png -------------------------------------------------------------------------------- /test/expected/percentage/gnu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/percentage/gnu.jpg -------------------------------------------------------------------------------- /test/expected/percentage/hamburg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/percentage/hamburg.jpg -------------------------------------------------------------------------------- /test/expected/percentage/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/percentage/wikipedia.png -------------------------------------------------------------------------------- /test/expected/quality/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/quality/Rhododendron.jpg -------------------------------------------------------------------------------- /test/expected/resize/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/resize/Rhododendron.jpg -------------------------------------------------------------------------------- /test/expected/resize/TeslaTurbine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/resize/TeslaTurbine.png -------------------------------------------------------------------------------- /test/expected/resize/gnu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/resize/gnu.jpg -------------------------------------------------------------------------------- /test/expected/resize/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/resize/wikipedia.png -------------------------------------------------------------------------------- /test/expected/samplingFactor/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/samplingFactor/Rhododendron.jpg -------------------------------------------------------------------------------- /test/expected/sharpen/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/sharpen/Rhododendron.jpg -------------------------------------------------------------------------------- /test/expected/upscale/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/upscale/wikipedia.png -------------------------------------------------------------------------------- /test/expected/upscale2/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/expected/upscale2/wikipedia.png -------------------------------------------------------------------------------- /test/fixtures/Rhododendron.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/fixtures/Rhododendron.jpg -------------------------------------------------------------------------------- /test/fixtures/TeslaTurbine.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/fixtures/TeslaTurbine.png -------------------------------------------------------------------------------- /test/fixtures/gnu.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/fixtures/gnu.jpg -------------------------------------------------------------------------------- /test/fixtures/hamburg.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/fixtures/hamburg.jpg -------------------------------------------------------------------------------- /test/fixtures/wikipedia.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/scalableminds/gulp-image-resize/88feeb34e49809c4fa96e8a7dbde9cf45e9c728c/test/fixtures/wikipedia.png -------------------------------------------------------------------------------- /test/image_resize_test.js: -------------------------------------------------------------------------------- 1 | /*global describe, it, before, beforeEach, after, afterEach */ 2 | 3 | var gm = require("gm"); 4 | var gm_im = require("gm").subClass({imageMagick: true}); 5 | var async = require("async"); 6 | var fs = require("fs"); 7 | var path = require("path"); 8 | var assert = require("assert"); 9 | 10 | const TMP_FOLDER = "tmp/"; 11 | const EXPECTED_FOLDER = "test/expected/"; 12 | 13 | var createTest = function(key, filename, comparisonTolerance) { 14 | if (comparisonTolerance === undefined) { 15 | comparisonTolerance = 0.1; 16 | } 17 | return function(callback) { 18 | 19 | var features, expected; 20 | 21 | var tmpFile = path.join(TMP_FOLDER, key, filename); 22 | var expectedFile = path.join(EXPECTED_FOLDER, key.replace("_imagemagick", ""), filename); 23 | 24 | async.waterfall([ 25 | 26 | function(callback) { 27 | fs.exists(tmpFile, function (tmpFileExists) { 28 | assert(tmpFileExists, tmpFile + " is missing"); 29 | callback(); 30 | }); 31 | }, 32 | 33 | function(callback) { 34 | fs.exists(expectedFile, function (expectedFileExists) { 35 | assert(expectedFileExists, expectedFile + " is missing"); 36 | callback(); 37 | }); 38 | }, 39 | 40 | function(callback) { 41 | gm(tmpFile).size(callback); 42 | }, 43 | 44 | function(_features, callback) { 45 | features = _features; 46 | gm(expectedFile).size(callback); 47 | }, 48 | 49 | function(_expected, callback) { 50 | expected = _expected; 51 | 52 | assert.equal(features.width, expected.width, filename + " width does not match"); 53 | assert.equal(features.height, expected.height, filename + " height does not match"); 54 | 55 | gm().compare(tmpFile, expectedFile, 0.1, callback); 56 | }, 57 | 58 | function(isEqual, difference, raw, callback) { 59 | assert(isEqual, tmpFile + " is not equal to " + expectedFile + " (difference: " + difference + ")"); 60 | callback(); 61 | } 62 | 63 | ], function (err) { 64 | if (err) { 65 | throw err; 66 | } else { 67 | callback(); 68 | } 69 | }); 70 | }; 71 | }; 72 | 73 | var createTests = function (key, filename) { 74 | return function(callback) { 75 | async.series([ 76 | createTest(key, filename), 77 | createTest(key + "_imagemagick", filename) 78 | ], callback); 79 | }; 80 | }; 81 | 82 | 83 | describe("resize", function () { 84 | it("should resize gnu.jpg", createTests("resize", "gnu.jpg")); 85 | it("should resize Rhododendron.jpg", createTests("resize", "Rhododendron.jpg")); 86 | it("should resize wikipedia.png", createTests("resize", "wikipedia.png")); 87 | it("should resize TeslaTurbine.png", createTests("resize", "TeslaTurbine.png")); 88 | }); 89 | 90 | describe("upscale", function () { 91 | it("should upscale with one dimension", createTests("upscale", "wikipedia.png")); 92 | it("should upscale with both dimensions", createTests("upscale2", "wikipedia.png")); 93 | it("should not upscale", createTests("no_upscale", "wikipedia.png")); 94 | it("should resize with the smallest dimension", createTests("no_upscale2", "wikipedia.png")); 95 | }); 96 | 97 | describe("crop", function () { 98 | it("should crop", createTests("crop", "wikipedia.png")); 99 | it("should crop with gravity", createTests("crop_gravity", "wikipedia.png")); 100 | it("should crop with only width set", createTests("crop_width_only", "wikipedia.png")); 101 | }); 102 | 103 | describe("sharpen", function () { 104 | it("should sharpen the Rhododendron image", createTests("sharpen", "Rhododendron.jpg", 0)); 105 | }); 106 | 107 | describe("filter", function () { 108 | it("should reduce Rhododendron image using catrom filter", createTests("filter", "Rhododendron.jpg", 0)); 109 | }); 110 | 111 | describe("samplingFactor", function () { 112 | it("should resize the Rhododendron image with a sampling factor of 4:2:2", createTests("samplingFactor", "Rhododendron.jpg", 0)); 113 | }); 114 | 115 | describe("convert", function () { 116 | it("should convert png to jpg", function (callback) { 117 | 118 | async.map([ 119 | path.join(process.cwd(), TMP_FOLDER, "convert", "wikipedia.jpg"), 120 | path.join(process.cwd(), TMP_FOLDER, "convert_imagemagick", "wikipedia.jpg") 121 | ], function (path, callback) { 122 | gm(path).format(callback); 123 | }, function (err, results) { 124 | if (err) { 125 | throw err; 126 | } else { 127 | results.forEach(function (format) { 128 | assert.equal("jpeg", format.toLowerCase()); 129 | }); 130 | callback(); 131 | } 132 | }); 133 | }); 134 | }); 135 | 136 | describe("quality", function() { 137 | var filename = "Rhododendron.jpg"; 138 | it("should resize with lower quality", createTests("quality", filename)); 139 | it("should have a smaller filesize", function (callback) { 140 | async.map([ 141 | path.join(TMP_FOLDER, "quality", filename), 142 | path.join(EXPECTED_FOLDER, "quality", filename) 143 | ], fs.stat, function(err, results) { 144 | if (err) { 145 | throw err; 146 | } else { 147 | var epsilon = 1024; 148 | assert(results[1].size - epsilon < results[0].size && results[1].size + epsilon > results[0].size, "size doesn't match"); 149 | callback(); 150 | } 151 | }); 152 | }); 153 | }); 154 | 155 | describe("noProfile", function () { 156 | var filename = "hamburg.jpg"; 157 | it("should remove all profiles (8bim, exif, iptc, xmp...) from the Hamburg image", function (callback) { 158 | async.map([ 159 | path.join(process.cwd(), TMP_FOLDER, "noProfile", filename), 160 | path.join(process.cwd(), TMP_FOLDER, "noProfile_imagemagick", filename) 161 | ], function (path, callback) { 162 | gm_im(path).identify("%[profiles]", callback); 163 | }, function (err, results) { 164 | if (err) { 165 | throw err; 166 | } else { 167 | results.forEach(function (format) { 168 | // test passes if result contains no or empty string elements 169 | assert.equal("", format, filename + " contains profiles '" + format + "''" ); 170 | }); 171 | callback(); 172 | } 173 | }); 174 | }); 175 | }); 176 | 177 | describe("flatten", function () { 178 | it("should flatten the wikipedia image", createTests("flatten", "wikipedia.jpg")); 179 | }); 180 | 181 | describe("interlace", function () { 182 | it("should interlace Rhododendron.jpg", createTests("interlace", "Rhododendron.jpg")); 183 | it("should interlace wikipedia.png", createTests("interlace", "wikipedia.png")); 184 | it("should interlace plus resize Rhododendron.jpg", createTests("interlace_and_resize", "Rhododendron.jpg")); 185 | it("should interlace plus resize wikipedia.png", createTests("interlace_and_resize", "wikipedia.png")); 186 | }); 187 | 188 | describe("percentage", function () { 189 | it("should resize gnu.jpg from percentage", createTests("percentage", "gnu.jpg")); 190 | it("should resize Rhododendron.jpg from percentage", createTests("percentage", "Rhododendron.jpg")); 191 | it("should resize wikipedia.png from percentage", createTests("percentage", "wikipedia.png")); 192 | it("should resize TeslaTurbine.png from percentage", createTests("percentage", "TeslaTurbine.png")); 193 | }); 194 | 195 | describe("cover", function() { 196 | it("should resize Rhododendron.jpg to 200px height", createTests("cover", "Rhododendron.jpg")); 197 | it("should resize TeslaTurbine.png to 200px width", createTests("cover", "TeslaTurbine.png")); 198 | }); 199 | --------------------------------------------------------------------------------