gulpgulp-imageminimagemin

How do I get the best PNG compression with gulp-imagemin + plugins?


I am trying to get the best setup possible for compressing pngs.

I have found there are some plugins available here for imagemin: https://www.npmjs.com/browse/keyword/imageminplugin

I have tried all the PNG options but the compression rates appear to be pretty bad.

pngquant appears to have the highest compression rate, (obviously the worst quality) similar quality to tinypng, but could still get nearer the tinypng figure.

Essentially I have 3 questions:

Question 1: Changing the options for both advpng & optipng doesn't seem to alter the filesize, here is an example, am I using this correctly? I am guessing that maybe it isn't using my settings at all and falling back to the default settings? If you notice the filesizes of these two are identical!:

.pipe(imagemin(
    imageminOptipng({
        optimizationLevel: 4
    })
))

Question 2: Am I using "pngout" in correctly? Is there a method to use it that I do not know about? The examples from their page seem not to work & neither does this method:

.pipe(imagemin([
    imageminPngout({
        strategy: 1
    })
]))

Question 3: Is there a better method to deal with png compression that I haven't yet found? Ideally I would somehow like to get a method that has the rate of pngquant, but the quality is a bit better.


Solution

  • After a long process of trials and errors, I've managed to get the imagemin-pngquant plugin to produce the image of the similarly small size as TinyPNG.com. Still a little bigger, but some parts of the image were looking better than the TinyPNG.com result.

    Input image size: 1.1MB
    TinyPNG.com: 223kb
    imagemin-pngquant: 251kb

    I used the next plugin settings:

    {
        quality: '70-90', // When used more then 70 the image wasn't saved
        speed: 1, // The lowest speed of optimization with the highest quality
        floyd: 1 // Controls level of dithering (0 = none, 1 = full).
    }
    

    Also, it may be a good idea to generate .webp images from .png and serve it to the browsers that support this format with the .png as a backup. More info about .webp image format: Google Developer Section

    After generating .webp from the optimized image (with the minimal quality loss) the image size was 62kB. You can use the imagemin-webp plugin with gulp-rename to stream images to the dist folder with the same base name, but different extension. Example gulp task:

    const config = require('./src/gulp/config.json');
    
    const gulp = require('gulp');
    const plugins = require('gulp-load-plugins')();
    const imageminWebp = require('imagemin-webp');
    
    gulp.task('images', function () {
        return gulp.src(config.src.images)
            pipe(plugins.imagemin([imageminWebp({
                method: 6,
            })]))
            .pipe(plugins.rename({ extname: '.webp' }))
            .pipe(gulp.dest(config.dist.images));
    });