4

I am trying to lossless optimize JPEG / PNG images with imagemin, but I have a problem when using extensions, they "deoptimize", meaning the result image is bigger than the original. How can I prevent this?

This is my Gruntfile.js

...
grunt.initConfig({
    imagemin: {
        jpeg: {
            options: {
                //by default it uses imageminJpegtran
                progressive: true,//default false, progressive JPEG is better compression https://superuser.com/questions/463477/progressive-jpeg-quality-compare-to-normal-jpeg
                arithmetic: false,//true breaks image

                //don't know how to use it loseless without making the images even bigger
                // use: [
                //  imageminMozjpeg({
                //      quality: 95, //Compression quality, in range 0 (worst) to 100 (perfect).
                //      dcScanOpt: 2,//2 Optimize between one scan for all components and one scan for 1st component plus one scan for remaining components
                //      arithmetic: false// false, or it breaks the image
                //  }),
                // ],
            },
            files: [{
                expand: true,
                cwd: '/www',
                src: ['**/*.{jpg,jpeg,JPG,JPEG}'],
                dest: '/www',
                filter: 'isFile'
            }]
        }
    }
});
...
Bharata
  • 13,509
  • 6
  • 36
  • 50
max4ever
  • 11,909
  • 13
  • 77
  • 115

2 Answers2

5

You have the answer in the title of your question – "grunt-contrib-imagemin". If you google it you will find this page on GitHub for Grunt.js as official Grunt GitHub site. On this page it is all described very detailed.

For example:

For imagemin OptiPNG plugin:

optimizationLevel (It is for PNG (for OptiPNG plugin) and NOT FOR JPG!)
Type: number
Default: 3
Select optimization level between 0 and 7.

The optimization level 0 enables a set of optimization operations that require minimal effort. There will be no changes to image attributes like bit depth or color type, and no recompression of existing IDAT datastreams. The optimization level 1 enables a single IDAT compression trial. The trial chosen is what OptiPNG thinks it’s probably the most effective. The optimization levels 2 and higher enable multiple IDAT compression trials; the higher the level, the more trials.

Level and trials:

  1. 1 trial
  2. 8 trials
  3. 16 trials
  4. 24 trials
  5. 48 trials
  6. 120 trials
  7. 240 trials

Do not try to use optimizationLevel for JPG! For JPG and PNG you will find different optimisation options. All the types of this optimization levels options are full described on the plugins sites (see the plugins listing below).

On this site you have a lot of plugins for different image types optimisation. In your case they are JPG and PNG (you have there also for WebP, Gif and SVG):

Plugins for JPG optimization:

Plugins for PNG optimization:

All PNG plugins have different optimization levels options. For example for AdvPNG plugin you have an optimizationLevel as option and you can select an optimization level between 0 and 4:

0 Don't compress
1 Compress fast (zlib)
2 Compress normal (7z)
3 Compress extra (7z)
4 Compress extreme (zopfli)

JPG optimization

And for JPG optimization I would like to recommend the mozjpeg and jpegoptim plugins because they have a lot of options for configuration – see the links for this plugins above.

Example of usage from plugins

const imagemin = require('imagemin');
const jpegoptim = require('imagemin-jpegoptim');
//const mozjpeg = require('imagemin-mozjpeg');
const pngquant = require('imagemin-pngquant');

(async () => {
    const files = await imagemin(['images/*.{jpg,png}'], 'build/images', {
        plugins: [
            //jpegoptim plugin for JPG
            jpegoptim({
                progressive: true, //Lossless conversion to progressive.
                max: 80 //try to set with and without this option
                //see other options on plugin site (link above) and take / add which you need
            }),
            /* As comment because on plugin page is nothing about lossless conversion
            // mozjpeg plugin for JPG
            mozjpeg({
                quality: 80
                //see other options on plugin site (link above) and take / add which you need
            }),*/
            //pngquant plugin for PNG
            pngquant({
                quality: [0.7, 0.8]
                //see other options on plugin site (link above) and take / add which you need
            })
        ]
    });

    console.log(files);
    //=> [{data: <Buffer 89 50 4e …>, path: 'build/images/foo.jpg'}, …]
})();

Source

For PNG lossless conversion try also to use the AdvPNG plugin without any options. optimizationLevel option for AdvPNG plugin is by default setted to 3 (from 0 to 4).

Advanced reading

It is very important to read the article:

Bharata
  • 13,509
  • 6
  • 36
  • 50
  • That is not an answer of how to do loseless with mozjpeg! Not even png – max4ever Jan 20 '19 at 12:08
  • @max4ever, I have added the example of how to use `mozjpeg` and `jpegoptim` plugins for JPEG few days ago. And for PNG I had it already in my answer. Unfortunately, I do not get any feedback from you. Please write me answer. – Bharata Jan 24 '19 at 07:26
  • so the jpegoptim { max: 80 } is lossless in your opinion? because i see the official documentation says "Set maximum image quality factor. (0-100). ", anyways I should have named this question how to use mozjpeg, but thanks – max4ever Jan 28 '19 at 14:01
  • By `max: 80` I wrote comment "try to set with and without this option". With this option it is not lossless. Even with `max: 99` is not because it is JPEG. But I wrote also `progressive: true, //Lossless conversion to progressive.` And I don't understand why you can not see this! I wrote very good answer, I have done a lot of research after a solution for you and I do not understand why I get only the criticism as feedback! It is really unfair! And for "how to use mozjpeg?" you can also find the answer in my answer – all is described on plugin page. For each plugin documentation I have links. – Bharata Jan 28 '19 at 14:41
1

You can use the optimizationLevel option. This value ranges from 0 to 7, with 3 as the default.

For instances:

imagemin: {
   dist: {
      options: {
        optimizationLevel: 5
      },
      files: [{
         expand: true,
         cwd: 'src/images',
         src: ['**/*.{png,jpg,gif}'],
         dest: 'dist/'
      }]
   }
}

In this example the images optimized are those with the extension png, jpg, or gif, and located in the “src/images” folder and all its subfolders. The result of the optimization will be stored in the “dist” folder.

Adapted from here.

Tiago Martins Peres
  • 14,289
  • 18
  • 86
  • 145