Using ImageMagick to make sharp web-sized photographs
even.li
even.li
There are many more good essays on image rescaling here: http://entropymine.com/imageworsener/
However, Safari ignores gamma and produces a flat gray rectangle when scaling down the Dalai Lama image, like Firefox does. I seem to remember that Safari used to do proper gamme correction in earlier versions, but they were pressured to abandon it because it was more important to give the result expected by websites.
ls *.jpg|while read i;do gm convert $i -resize "900x" -unsharp 2x0.5+0.5+0 -quality 98 `basename $i .jpg`_s.jpg;done
The part I take issue with is the unnecessary invocation of `ls`. The shell does the glob expansion. A `for` loop is better suited for this. Also, if using bash,* we can get rid of basename. for file in *.jpg; do gm convert $file -resize "900x" -unsharp 2x0.5+0.5+0 -quality 98 ${file%.jpg}_s.jpg; done
* zsh fans, I'm sure it works there too.Get in the habit of putting $file (and, in this case, ${file%.jpg}_s.jpg) in double quotes. Your one-liner (and theirs) will blow up spectacularly if there's whitespace in a filename:
bash-3.2$ for i in 'lots of spaces'.jpg '1 2'.jpg; do printf 'arg = %s\n' ${i%.jpg}_s.jpg; done
arg = lots
arg = of
arg = spaces_s.jpg
arg = 1
arg = 2_s.jpg
bash-3.2$ for i in 'lots of spaces'.jpg '1 2'.jpg; do printf 'arg = %s\n' "${i%.jpg}_s.jpg"; done
arg = lots of spaces_s.jpg
arg = 1 2_s.jpg
EDIT: It's also worth noting that, by default, zsh doesn't split on whitespace in parameter expansion like sh, bash, etc. do. ("man zshexpn" and search for "SH_WORD_SPLIT") basename -s .jpg -a *jpg |
xargs -I{} convert "{}.jpg" \
-resize "900x" -unsharp 2x0.5+0.5+0 -quality 98 "{}_s.jpg"
EDIT: weird line breaking is to prevent sidescroll boxThe advantages of having correctly sized imagery are immense, but in short.. something like 70% smaller total byte payload for mobile, huge reduction in image decode & resize cost, better scroll performance, and faster relayouts when orientation changes or browser window changes.
(And I do think browsers themselves should resample scaled images like this to achieve equal quality, but your users will benefit way more if assets are delivered well to begin with.)
This shouldn't be automated by a plugin AT ALL, and should be done based on the type of image it is. (icons, clipart, logos, etc. would make poor subjects).
> pagespeed EnableFilters resize_images;The biggest problem of scaling down an image is to find right settings for resampling and sharpening. After many expreiments, I found it impossible to achieve good results by simply running convert with a line of arguments. So I came up with this script, which basically does the following:
* configures -interpolate bicubic -filter Lagrange; * resizes source image 80%; * applies -unsharp 0.44x0.44+0.44+0.008; * repeats steps 2 & 3 until target size is reached.
Do you have any suggestions when there are thousands of images and all this needs to be automated?
It can distribute the work across the available CPU cores, and it can even distribute the work across different machines using SSH: https://www.gnu.org/software/parallel/man.html#example__dist...
Unsharp masking is mostly aesthetic. For an image like the example, a mountainside, it gives you a feeling of crisp details, but there isn't any more data there. It looks great on a landscape, but it can be disastrous on a portrait of a person (pores and stubble will be highlighted, usually in an unpleasant way).
(EDIT: incorrect assertion about unsharp masking before or after scaling removed)
Sometimes it's better to unsharp-mask it to a degree that looks slightly oversharpened at a large size, but looks great when reduced - especially for very small images, like avatars or other icons.
Unsharp mask doesn't work that way: you get the same results applying it before or after scaling, as long as you adjust the radius accordingly.
The reason I suggested applying it after scaling is because aesthetically pleasing settings don't change much as the image size changes.
(Awesome stuff! That looks like a fun company to work for or found.)
Interestingly, we've done WebP support, and while the files are smaller across the board, visual quality deteriorates really quickly once you start dropping that quality value, even in small increments.
Though the amount of sharpening can depend on the context : photographers tend to be annoyed by over-sharp images, while on a marketing website it might be good idea to make the pictures pop.
For optimal images, you could do something like this:
1) Resize the image (And apply the trick from this article) use the proper quality marker (anywhere between 85-95)
2) Run it through Imageoptim
If you want a commandline version of ImageOptim, I have had good results with https://github.com/toy/image_optim
An example:
http://www.andrewmunsell.com/blog/
Scroll down to the "Now is the Future" blog post. The cover image of the Seattle skyline is 1700x666 and ~65kb (though, it's been recompressed into WebP by mod_pagespeed if your browser supports it). The JPG (before WebP conversion) is ~88kb.
To see it without the recompression and turn mod_pagespeed off, you can look at the image on the page:
Granted, my games use high-res hand-drawn vector-ish art (not pixel art, neither photo-style or paint-style art) so I dunno if this is applicable to photos.
for image in *.jpg ; do gm convert $image -resize "900x" -unsharp 2x0.5+0.5+0 -quality 98 `basename $image .jpg`_s.jpg ; done
Neither of them deal with filenames with \n in them, eg 'pretty
sunset.jpg'
For that, you'll want to run find:
find . -name '*.jpg' -exec convert '{}' -resize "900x" -unsharp 2x0.5+0.5+0 -quality 98 `basename '{}' .jpg`_s.jpg \;Of course, you can always make them even sharper with filters if you want.
Much better appearance for the same file size.
Unfortunately, I don't have any examples handy.
I was going to suggest that the real problem is people using IE8 but that wouldn't go too well I guess
"If you hover the mouse on the image, you'll see the sharpened version."
>How do I resize a whole folder of images? [...]