Creating a CodeKit 3 Hook Tutorial - for Webp & JPEG2000 image conversion
Despite writing the most comprehensive review of Codekit on the internet, there's a feature I've never spent much time within Codekit: hooks. Most of my day-to-day dev is now in Gulp/Grunt/Webpack thus I haven't dedicated the time to set up a hook. Personal antidotes aside here's a quick tutorial on how to get started with CodeKit Hooks, using a simple bash script to hook into the exceptionally powerful ImageMagick.
I highly recommend checking out my previous post on JPEG 2000 and WebP for a more in-depth look at creating JPEG 2000 and WebP assets manually. The quick and short is there are (somewhat) better image formats that have been developed for lossy image compression, as the JPEG format is now 25+ years old. Modern web browsers support a smattering of new formats, but no single format is the clear winner. Safari supports JPEG2000 and HEIF(barely). Chrome/Opera support WebP. IE11/Edge supports JPEG XR. WebP/JPEG2000/JPEG-XR all support alpha layers, and presumably HEIF. JPEG2000 / WebP supports both lossy and lossless image compression and JPEG-XR and JPEG2000 8-10 bit color. Firefox in atypical new format crisis the laggard (Remember Ogg anyone?). Sadly, JPEG-XR is a headache due to proprietary hell and is mostly absent on macOS(OS X) or Linux, and HEIF is too avant-garde. BPG is pretty much DOA.
Creating a Hook
CodeKit 3 hooks allow CodeKit to tap into your Mac's terminal or Applescript, and trigger scripts to process files. The aforementioned can be exceptionally handy. CodeKit's documentation is pretty solid for getting started with hooks but novice and junior devs might be a bit perplexed as to how or why you may want to do this.
For those who haven't used or perhaps heard of ImageMagick, it is a CLI utility that allows you to process images in any number of ways, like batch convert file formats, scale images, add borders, remove alpha masks and more. This tutorial only includes a very particulary example of ImageMagick and will require some basic terminal usage. If you'd like to learn more basics of ImageMagick, I suggest reading Process images for your blog with ImageMagick. Most novice developers should feel comfortable with the terminal enough to understand the few basic lines of code in this project. Junior developers should always be wary of executing random terminal commands, especially ones that ask you use sudo commands. All the bash scripts presented should be harmless and do not require sudo.
Step 1 - Homebrew
Install HomeBrew. In your terminal, type:
If running the previous command returns "command not found", go to Homebrew's website, which should have the installation instructions on the first page.
Step 2 - Installing ImageMagick
Once homebrew has been installed or verified that it has been previously installed, its time to install ImageMagick with JPEG2000 support as by default it does not come pre-baked with JPEG2000 support or WebP. Fortunately, WebP only requires installing separately.
Note: If you have a previous version of ImageMagick installed, you may need to run brew uninstall imagemagick
to include JPEG2000 support. Annoyingly, ImageMagick will merely write JP2 files as the source file's file format if OpenJPEG is not present but with the caveat of appending the file with the new file suffix. This is very confusing, misleading, and frustrating. It took me roughly an hour to deduce that JPEG2000 requires OpenJPEG with ImageMagick. If you find ImageMagick creating JPEG2000 files that are massively larger than a PNG, Run magick identify -verbose filename
to see if your JPEG2000 is truly a JPEG2000. If it reports your .jp2 file as a PNG, then you are missing OpenJPEG.
Step 3: Creating a CodeKit 3 Hook
In CodeKit, click on the gear icon, and click hooks. Click add a new hook. For this example, we're going to create a Shell script (Terminal bash script). Codekit has its own variables that can be passed into your shell script.
The basics of converting files in ImageMagick is pretty simple:
ImageMagick will export the file type based on you the suffix you choose. My goal is to create both a JPEG2000 and WebP image using ImageMagick in the same directory as the original PNG.
NNotably, there are many ways to go about this, but I went for simple. Here's a quick rundown of what the following code does:
$CK_INPUT_PATH
and$CK_OUTPUT_PATH
are both CodeKit 3 variables that are passed into a shell script. You can read about them here.webpExt=".webp"
andjp2Ext=".jp2"
are bash vars I use to append a file name.${CK_OUTPUT_PATH%.png}
removes .png from the output path.webpFile="${CK_OUTPUT_PATH%.png}"$webpExt
makes a variable with the correct path/filename - .png suffix + .webp suffix. JPEG2000 support convert $CK_INPUT_PATH -quality 75 $webpFile
runs ImageMagick's convert function on the CodeKit input file and then processes it with quality 75, and exports it the CodeKit 3 location with the proper file type that I set up in previous steps.- I repeat this on JPEG2000.
Pretty simple right?
Hopefully, it was. If it wasn't, don't sweat it. The terminal is pretty much using a computer without handrails. CodeKit may buffer you from the terminal, but it's entirely worth your time as a developer to get comfortable with it and expected in most types of development.
The quality settings will need to be tweaked. Often its better to do this sort of processing hand as I've had some wildly varying results on JPEG2000 and WebP, but this is a simple way batch convert PNGs to WebP and JPEG2000 images, so Chrome/Safari users (99% of North American mobile users) can enjoy smaller image file sizes. Also, PNG with CodeKit's ImageOptim on PNGs can be hyper-effective, and for simple images often best JPEG2000 and Webp.
Bonus: MozJPEG
If you'd like to use PNGs as sources, you can also create JPGs of your images using MozJPEG. MozJPEG only supports a few input formats. This script assumes you have a high-quality PNG. Its recommended not to use Codekit's PNGquant on the source PNG. Notably, this script could be exampled using ImageMagick accept @2x only images and resize them. Here's a more involved script that will take Retina PNGs and convert them into 2x and 1x JPEG2000, JPEG, and WebP. The quality setting is arbitrary. You'll want to set up a source folder and build folder otherwise you'll end up with recursive files.
Install MozJPEG
Bash Script for CodeKit (read above for notes)
Double bonus
I ported the same script as above to a jenky UI meant to be used outside of CodeKit.
Update August 19, 2017 - Added second script with image resizing + MozJPEG and corrected missing WebP installation step.