Convert images for web using the Sips command line on MacOSX
We will see how to convert a folder of images to make them safe for web using the Mac OSX command line tool Sips. First in a shell script and then an AppleScript version if you want to share this functionality with less technical users.
There are obviously many ways to convert images for web. Some of them are tedious if you have a whole folder to convert. In this case I would generally use ImageMagick. I am quite familiar with it because I do pretty much any scripted image processing with it. I use it for resizing, composition, treatment, etc. ImageMagick is pretty much a photoshop that you can control with text. It is fairly simple considering what you can do with it, but the number of options can be intimidating if you are trying to do something simple.
There are other simpler tools when you just want to bulk convert images for web. If you happen to be on Mac OSX, then you already have sips
installed. The good thing with this is that if you share a double-clickable script with somebody who is not technical, you can be sure that if they are on Mac OSX they have sips
available.
The command sips
is basically the low level command for images modifications. It allows us to resize images, rotate, flip, pad, change their color space, etc. Pretty much anything you can do with "Preview.app". Here is the man page. But you can access it from the command line with the traditional:
$ man sips
Now if we want to convert images for web, we want to make sure of the following:
- The image is in a format like jpeg or png.
- The image 72dpi.
- The image is compressed to minimize loading time.
- The image is reasonably wide.
- The image is RGB.
Let’s start with the simplest thing and convert our images to jpeg. That way, we will get the details of the command.
$ cd /path/to/my/images/folder/
$ mkdir ../web
$ sips -s format jpeg * --out "../web/"
So the basics are that we move to the folder containing images. We create a destination folder called “web”. Then we use the sips
command running it on all files because I've put *
. In reality you want to make sure these are image files, you can use a glob like this instead which uses extended glob: ?(*.jpg|*.jpeg|*.tif|*.tiff)
. Again simplified, you might to include more formats and their uppercase version. At the end we specify the destination folder with `--out "../web/".
But the most interresting part is obviously the -s format jpeg
. This turns the output into a jpeg and follows a pattern common with most arguments of sips
. You set an attribute with key and value. The -s
is indeed followed with 2 words. I haven't seen this on many commands.
Now let’s add compression to our sips command:
$ sips -s format jpeg -s formatOptions high * --out "../web/"
As you can see the argument follows the same pattern with -s
. The value can either be a number which will be interpreted as a percentage of compression like "80". Or you have keywords describing the quality like "best", "high", "normal" and "low".
Now let’s add the image resolution:
$ sips -s format jpeg -s formatOptions high -s dpiWidth 72 -s dpiHeight 72 * --out "../web/"
Again quite explicit and following the same pattern. You want to set it for the width and the height. And there you have it: 72 dpi.
Now for the resizing there are many options or strategies. You can read the man page for more details, but I went for the -Z
option which sets the longest side of the image. That is to say with "1600", the output will be 1600 pixels wide if it is a landscape image, or 1600 pixels high if it is a portrait image.
$ sips -s format jpeg -s formatOptions high -s dpiWidth 72 -s dpiHeight 72 -Z 1600 * --out "../web/"
Now let’s add the trickiest part and make the output RGB.
$ sips -s format jpeg -s formatOptions high -s dpiWidth 72 -s dpiHeight 72 -Z 1600 -m '/System/Library/ColorSync/Profiles/sRGB Profile.icc' * --out "../web/"
I said “tricky”, it is not that it is necessarily complicated but you need to reference a color profile file and it is not obvious where to find one of these on your machine. I did not find the location on the man page. You need a color profile because basic equivalence between RGB and CMYK is not ideal. You can read more about this on the article about colors of our Color Converter application. I am not sure this is the simplest way to make an image RGB, and I am not sure the file is always at the same location on all versions of OSX. But it is quite likely if you have a fairly recent version.
So there you have it. A script to convert images for web. As an extra, here is a little AppleScript which does pretty much the same thing but ask for details like width and compression with a simple GUI so that it can be used without fiddling with code. This is an ideal way to package a functionality to share with somebody who is not technical. Just open it with the AppleScript editor and export it as an App.
The AppleScript has a slightly different behavior though. It does filter files in the folder so that you convert only image files. You can obviously modify this list of formats. And the destination folder is created inside the folder containing the images. And this folder is created for you if it does not exist yet.
Here you go:
tell application "Finder"
set myFolder to choose folder
set myFiles to files of myFolder whose name extension is in {"jpg", "jpeg", "tif", "tiff", "png", "JPG", "JPEG", "TIF", "TIFF", "PNG"} if (exists folder "web" of folder myFolder) is false then
make folder at myFolder with properties {name:"web"}
end if set widthChoices to {"1600", "800", "400"}
set widthChoice to {choose from list widthChoices with prompt "Pick a width"}
set qualityChoices to {"high", "normal", "low"}
set qualityChoice to {choose from list qualityChoices with prompt "Pick a quality"}
set formatChoices to {"jpeg", "png"}
set formatChoice to {choose from list formatChoices with prompt "Pick a format"} set imgPaths to ""
repeat with myFile in myFiles
set imgPaths to imgPaths & quoted form of POSIX path of (myFile as text) & " "
end repeat set destinationFolder to myFolder & "web:" as string
set destinationFolder to quoted form of POSIX path of destinationFolder do shell script "sips -s format " & formatChoice & " -s formatOptions " & qualityChoice & " -Z " & widthChoice & " -s dpiWidth 72 -s dpiHeight 72 -m '/System/Library/ColorSync/Profiles/sRGB Profile.icc' " & imgPaths & " --out " & destinationFolder display dialog "Done !"end tell