gulp-image-resize to generate multiple output sizes

Viewed 5373

I'd like to use gulp to generate a bunch of different image sizes and optimize them at the same time. I think there are two approaches to this problem:

The first is that you could create n different tasks for each size, then create a master task that calls each resize task. The master task might look something like:

gulp.task('resize_images',['resize_100','resize_300','resize_800','resize_1000']);

This seems ok, and you'd get good parallelization, but there is a lot of duplicated code for each task which means maintaining it could be a nightmare if the list of sizes grows large enough.

The other idea I'd had was to create a single task, but use a for loop within it to iterate over each size. Like so:

var gulp = require('gulp');
var imageminWebp = require('imagemin-webp');
var imageResize = require('gulp-image-resize');
var notify = require('gulp-notify');
var os = require('os');
var parallel = require('concurrent-transform');
var pipes = require('gulp-pipes');

gulp.task('resize_images', function() {

    var sizes = [100,300,800,1000,2000];
    var stream;

    for (size in sizes) {
        stream = gulp.src('images/master/**/*.{jpg,png,tiff}')
            .pipe(parallel(
                    imageResize({
                        width:  sizes[size],
                        height: sizes[size],
                        upscale: false
                }),
                os.cpus().length
            ))
           .pipe(pipes.image.optimize())
           .pipe(gulp.dest('images/derivative/' + sizes[size] + '/'))
           .pipe(imageminWebp({quality: 75})())
           .pipe(gulp.dest('images/derivative/' + sizes[size] + '/'))
   }
   return stream;
});

This seems ok, but doesn't feel gulp-y for some reason. For example, notifications are weird with the solution above - I'd like to notify when each is size is done processing, which I get for free with the single master task. Is there a better way to accomplish what I'm trying to do?

2 Answers

For Gulp 4:

var imagemin = require('gulp-imagemin');
var imageResize = require('gulp-image-resize');
var rename = require("gulp-rename");

function images(cb) {
  [100, 300, 800, 1000, 2000].forEach(function (size) {
    gulp.src('src/images/**/*.{jpg,jpeg,png}')
      .pipe(imageResize({ width: size }))
      .pipe(rename(function (path) { path.basename = `${path.basename}@${size}w`; }))
      .pipe(imagemin())
      .pipe(gulp.dest('dist/images'))
  });
  cb();
}

The callback is used to signal async completion (required by Gulp 4).

Related