Web Content Optimization: Images
Unless we are careful when creating them or manipulating them with Photoshop or its equivalent images can become huge very quickly. If we're not careful when saving the images we will find ourselves with images that are way larger than they need to be.
Photoshop (or your favorite image editor) save for the web #
The simplest way to compress your images is to save for web. I can hear your laughter but it still holds that most of us will use Photoshop, or something similar to it, to create and manipulate images. So it makes sense to figure out how to best compress your images in the platform you create them or manipulate them.
One thing to remember is that compressing your image or reducing its dimensions can cause issues like pixelation and visible loss of quality. I would never say don't compress your images but I will always say use your judgment when doing so.
Photoshop CC #
Photoshop has always provided a save for web feature. Information for (older versions of) Adobe Photoshop CC can be found in the Adobe Help Website.
Newer versions of Photoshop 2015 still maintain the save for web for legacy compatibility but now recommend using the export as feature instead.
GIMP #
The GNU Image Manipulation Program (GIMP) provides the facilities to both scale and compress images. It is an open-source equivalent to Photoshop and it's available for most major platforms: Mac, Windows and Linux.
Command line tools #
Lately, I've been working on command line tools and build workflows using Grunt and Gulp. Because it is command line based and uses Node as the driving force Gimp and Photoshop do not work or would take much longer to develop than it would take using the tools below.
Imagemagick #
ImageMagick is an older image processing and manipulation package first released in 1987. While commands like Imagemin (discussed below) are geared only towards image compression, Imagemagick can perform multiple tasks.
The following grunt task illustrates some of the things you can do with Imagemagick.
The first section will create multiple resolution files, like those you'd use for responsive images, for each jpg file with the indicated extension - The second session will take the files from the test directory, resize them and copy the resulting file into the test/resized directory - The last section will take the test/resizeme.jpg file, resize it to a 25x25px image and save the resulting file as resize-me-small.jpg
"imagemagick-hisrc":{
dev:{
files:"**/*-2x.jpg",
suffix:["-2x","-1x","-low"],
}
},
"imagemagick-resize":{
dev:{
from:'test/',
to:'test/resized/',
files:'resizeme.jpg',
props:{
width:100
}
}
},
"imagemagick-convert":{
dev:{
args:['
test/resizeme.jpg',
'-resize', '25x25',
'test/resized/resizeme-small.jpg']
}
}
Imagemin #
Imagemin is a command line image compression utility that is primarily designed to work as a command line and GUI application(Mac, Linux and Windows) as well as build workflows such as Grunt and Gulp task runners
It comes bundled with the following optimizers:
- gifsicle — Compress GIF images
- jpegtran — Compress JPEG images
- optipng — Compress PNG images
- svgo — Compress SVG images
I've seen mozjpeg recommended as an alternative compressor for JPEG images.
Please note that the task below only works with JPEG and PNG images. I know that I don't have any GIF or SVG images in the project.
imagemin: {
png: {
options: {
optimizationLevel: 7
},
files: [ {
// Set to true to enable the following options…
expand: true,
// cwd is 'current working directory'
cwd: 'images/',
src: ['**/*.png'],
dest: 'dist/images/',
ext: '.png'
}
]},
jpg: {
options: {
progressive: true,
use: [mozjpeg()]
},
files: [{
// Set to true to enable the following options…
expand: true,
// cwd is 'current working directory'
cwd: 'images/',
src: ['**/*.jpg'],
dest: 'dist/images/',
ext: '.jpg'
}]
}
},
And the (partial) result of running the task above:
Running "imagemin" task
Running "imagemin:png" (imagemin) task
Verifying property imagemin.png exists in config...OK
Files: images/Mosaic_Netscape_0.9_on_Windows_XP.png
-> dist/images/Mosaic_Netscape_0.png
Files: images/Navigator_1-22.png
-> dist/images/Navigator_1-22.png
Files: images/cern-webservices-archive.png
-> dist/images/cern-webservices-archive.png
Files: images/coffee2.png
-> dist/images/coffee2.png
Files: images/font-in-chrome-mac.png
-> dist/images/font-in-chrome-mac.png
Files: images/font-in-spartan-win-vm.png
-> dist/images/font-in-spartan-win-vm.png
Files: images/font-terms.png
-> dist/images/font-terms.png
Files: images/fonts-in-use-example.png
-> dist/images/fonts-in-use-example.png
Files: images/full-width-translated-object.png
-> dist/images/full-width-translated-object.png
Files: images/hyperreal-org-1996-archive.png
-> dist/images/hyperreal-org-1996-archive.png
Files: images/kerning.png
-> dist/images/kerning.png
Files: images/mag_001.png
-> dist/images/mag_001.png
Files: images/mag_002.png
-> dist/images/mag_002.png
Files: images/mag_003.png
-> dist/images/mag_003.png
Options: interlaced, optimizationLevel=3, progressive
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/Mosaic_Netscape_0.9_on_Windows_XP.png (saved 824 B - 1%)
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/font-terms.png (saved 23.85 kB - 39%)
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/cern-webservices-archive.png (saved 22.08 kB - 19%)
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/Navigator_1-22.png (saved 19.64 kB - 63%)
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/kerning.png (saved 854 B - 5%)
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/font-in-spartan-win-vm.png (saved 77.43 kB - 43%)
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/font-in-chrome-mac.png (saved 31.71 kB - 23%)
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/coffee2.png (saved 17.9 kB - 13%)
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/fonts-in-use-example.png (saved 23.59 kB - 13%)
<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="<img draggable="false" class="emoji" alt="✔" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>" src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png"/>"
src="//s.w.org/images/core/emoji/72x72/2714.png">
images/hyperreal-org-1996-archive.png (saved 21.84 kB - 17%)
. . .
Minified 14 images (saved 799.53 kB)