Geof Crowl

I’m a software designer currently living in Salt Lake City, Utah. I like to make nice apps and websites. Sometimes I share things of interest here. Subscribe to the RSS feed with my open source reader.
On The Web

Twitter, Strava, LinkedIn, Instagram, GitHub, email

Air Lookout, Simple Pacer, Super Simple RSS
Suggested Reading
Salt Lake City Canyon Info For Bikes
Introducing Air Lookout 2
Collection of Human Interface and Software Design Guides
Air Lookout 1.4: All The Complications
Kawasaki KLR 650 Rebuild Compilation

Thursday, April 23rd 2020

Guetzli JPEG Image Comparison #

I have been using the guetzli image encoder from Google and I’m really impressed with the results that it is able to deliver.

Here’s a quick comparison using a photo that I recently took with an iPhone Xs that would potentially be a problematic image for most JPEG encoders. It is straight from the camera and not edited.

Below are all 800× 600 crops of the encoded images exported at 200% as a PNG (a lossless format). The original full size photo from the iPhone was given to the encoders.

All exports/encodings were done on my iMac (27-inch Retina Late 2015) with Intel Core i7-6700K @ 4.0 GHz (4 cores).

Original Photo

Original JPEG from iPhone Xs

View crop of original

Photoshop JPEG Export Quality 30

Photoshop export at 30 quality

View crop of Photoshop export at 30 quality

Guetzli JPEG Encode Quality 80

Guetzli encode at 80 quality

View crop of guetzli encode at 80 quality

When exporting large photographic images at retina resolutions for the web, it’s fairly common to export at the full retina (2x) resolution but drop the JPEG quality down to 30 or 40.

This is exactly what I did with the first Photoshop export. These results are fairly in-line with what I would expect and aim for.

However, for the guetzli JPEG encode, I was able to bring the quality all the way up to 80 and still have the resulting image be 0.4MB smaller.

Here’s what I noticed about the guetzli export:

Photoshop JPEG Export Quality 80

Photoshop export at 80 quality

View crop of Photoshop export at 80 quality

To be fair to Photoshop, here’s what Adobe’s JPEG encoder can do at a quality of 80. While the visual quality is definitely improved (no sky banding, better color), the file size has grown to be larger than the original photo!

Where did this extra information come from (around 0.2MB!)?! I assume that the increased file size is because iOS has a more optimized Huffman table than Adobe Photoshop. I also don’t know what JPEG quality the iOS JPEG encoder is aiming for (there is some slightly noticeable compression in the original JPEG1 if you look closely).

Due to the resulting increase in file size, I would never be able to export large photographic retina assets for the web at this quality using the Photoshop JPEG encoder.

Guetzli JPEG Encode Quality 30

Guetzli export at 30 quality

View crop of Guetzli export at 30 quality

Inversely, here’s what guetzli is capable of doing with a quality of 30.

I’ve noticed that below 60 quality, the resulting JPEG can be quite poor with a lot of JPEG artifacts. While the sky maintains a reasonable gradient with minimal banding, the sharpness of the ridge-line is gone and the JPEG compression in the branches has become quite extreme and now lacks sharpness. In some ways, I would consider this to be lower visual quality than the Photoshop export at 30 quality.

While the actual visual quality has dropped tremendously this has only saved 0.4MB on a 12MP photo. When I export JPEG images for the web, I always try to find these steep quality reductions. The higher visual quality of the guetzli encode at 80 for only 0.4MB (~20% increase in file size) in this scenario would be an easy decision for me.

Photoshop JPEG Export Quality 100

Photoshop export at 100 quality

View crop of Photoshop export at 100 quality

I also wanted to see what these two encoders could do at a quality of 100. What’s interesting about this Photoshop export is that although the resulting visual quality is quite good, the file size is considerably larger than the original photo! Again, I am interested to know where this extra information come from (an additional 3MB!).

Guetzli JPEG Encode Quality 100

Guetzli export at 100 quality

View crop of Guetzli export at 100 quality

Fortunately sanity has been restored (at least in this scenario) and the resulting encoded JPEG is smaller than the original photo! Like the other high quality exports, the visual quality is incredible but the file size is just too large.

It’s worthwhile to note how steep the file size drop-off can be with guetzli. From a quality of 100 to 80 we saved 3.5MB (around 57%) without much loss of visual quality.

I always search for these sweet spots when creating JPEG assets for websites. I wish there were image export tools that could automatically export images at a variety of quality levels and optimizations and graph the resulting file sizes next to their respective image previews. It would save me a ton of time.

Guetzli JPEG Encode Quality 1

Guetzli export at 1 quality

View crop of Guetzli export at 1 quality

Out of curiosity I wanted to see the extreme lowest quality that Photoshop and guetzli would encode.

It should be noted that the guetzli quality 1 and quality 30 JPEG files are the exact same file size. Running md5 on both guetzli JPEGs at quality 30 and 1 confirms that these are the exact same files.

I suspect the guetzli encoder has not been optimized for these very low quality levels or might be hitting a bottom barrier or threshold for the algorithm. This also makes me wonder if the above quality 30 has already hit that barrier and what quality level that barrier is really at.

Photoshop JPEG Export Quality 1

Photoshop export at 1 quality

View crop of Photoshop export at 1 quality

This quality 1 from Photoshop is definitely not usable for this specific image. To Adobe’s credit, their algorithm does appear to be continuing to save file size beyond the quality 30 export (1.4MB or about 50%).

It may seem like a goofy test, but occasionally there are simple photographic images that can look reasonably good at JPEG quality levels of 10 or 20.

Comparison Of Quality 100, 80 And 30 From Guetzli And Photoshop

Comparison of original, guetzli and photoshop JPEG encoders

View full size comparison


Encoding JPEGs with guetzli can create visually high quality results with considerably smaller file sizes than other comparable tools. However, this all comes at a computational cost. While spending more than 20 minutes for a 12MP photo likely doesn’t make sense for photographers, it does make sense for web and app designers or developers.

Spending a few extra minutes to encode a large and prominent image in a way that saves megabytes of file size on a website that could be downloaded and viewed by millions seems reasonable to me. My hope is that design tools like Photoshop, Sketch or Figma will update their image exporting process to optionally use guetzli in the future (although I won’t be holding my breath…).

Unfortunately compiling C++ programs and editing shell scripts is out of reach for most designers. I hope that other peripheral tools like ImageOptim will support guetzli encoding soon.

If you aren’t afraid of installing ports via Homebrew or the command line and you regularly work with JPEGs, I’d strongly recommend giving guetzli a try.

Let me know on twitter if you have used guetzli before or you found this post helpful.

Also: R.I.P. JPEG2000

Full Files

Here are all the full, not cropped, encoded and exported JPEGs that are referenced above.


The guetzli tool from Google disables all quality settings below 84. I do not understand this decision.

If you try to export at a quality setting below 84 it gives the user this response:

Guetzli should be called with quality >= 84, otherwise the output will have noticeable artifacts. If you want to proceed anyway, please edit the source code.

I took their advice. I created a fork of Google’s guetzli project and disabled the test for quality levels below 84.

rectangular/guetzli on Github

I also created a bash script to speed up encoding a folder full of images using JPGs. While guetzli will not take advantage of additional CPU cores or threads, this shell script will start simultaneous guetzli encoding tasks to keep your CPU busy. Warning: guetzli encoding is very CPU intense and using my shell script will demolish your computer for many minutes. However, you will have some nice JPEGs in a relatively short amount of time.

rectangular/ gist on Github

It should also be noted that guetzli is not aware of JPEG rotation data or embedded color profiles. This is unfortunately not the first time that JPEG rotation data has caused me additional frustration.


An Interactive Introduction to Fourier Transforms(via):

Fourier transforms are a tool used in a whole bunch of different things. This is an explanation of what a Fourier transform does, and some different ways it can be useful.

Did you know Fourier transforms can also be used on images? In fact, we use it all the time, because that's how JPEGs work! We're applying the same principles to images – splitting up something into a bunch of sine waves, and then only storing the important ones.

After publishing my post I was lead to this great interactive article on Fourier transforms. I think Fourier transforms finally clicked for me and how JPEGs use them.

1Why did I use a JPEG for my input file and not RAW, HEIF or a lossless format? Most clients and web projects get their image assets from stock photo websites. Typically these are high quality JPEGs. It would be unrealistic to mimic web asset creation by using a lossless image file as an input to the encoders.

2The file that was generated by guetzli at quality 1 is the exact same file as was generated at quality 30. I included it anyways.

Saturday, April 18th 2020

What To Watch: AlphaGo #

This documentary mostly follows AlphaGo (Google’s Go playing AI) competing against Lee Sedol (one of the top ranked Go player in the world).

I don’t know much about Go but I found the documentary to be extremely interesting. I strongly believe that computers should be used to make humanity smarter and not to be a crutch to make us dumber. It’s amazing to watch AlphaGo be a catalyst for one of the world’s best Go players who has to rethink his understanding of Go in order to attempt beating this AI.

If you have a spare hour and a half, I’d consider watching it.

AlphaGo Documentary on YouTube

Monday, April 13th 2020

What To Watch: Volvo Ocean Race 2017–2018 #

The inside-story of what it takes to win sailing’s iconic race around the world, and the ultimate test of a team in professional sport. Seven fully professional sailing teams battle to claim ocean racing’s greatest prize, in a race that covers 11 legs over 45,000 nautical miles, taking in 12 major cities and six continents.

I am forever fascinated by extreme endurance challenges. There aren't many that can compare to the 9 month long sailboat race around the world that is the Volvo Ocean Race. It has the tech of F1, the navigation of an adventure or orienteering competition, the weight consciousness of pro cycling, the brutality of the Dakar and survival challenges not quite like anything else.

If you have some spare TV time, I think you'll find this entertaining. The entire documentary series is on YouTube free of charge.

The Volvo Ocean Race 2017–2018 playlist on YouTube

Wednesday, March 25th 2020

Apple Updates HIG To Include Pointers On iPadOS #

Apple: Pointers (iPadOS):

iPadOS 13.4 introduces dynamic pointer effects and behaviors that enhance the experience of using a pointing device with iPad. As people use a pointing device, iPadOS automatically adapts the pointer to the current context, providing rich visual feedback and just the right level of precision needed to enhance productivity and simplify common tasks.

With a content effect, the UI element or region beneath the pointer can also change its appearance when the pointer hovers over it. Depending on the type of content effect, the pointer can retain its current shape or transform into a shape that integrates with the element's new appearance.

iPadOS defines three content effects that bring focus to different types of interactive elements in your app: highlight, lift, and hover.

The highlight effect transforms the pointer into a translucent, rounded rectangle that acts as a background for a control and includes a gentle parallax. The subtle highlighting and movement bring focus to the control without distracting people from their task. By default, iPadOS applies the highlight effect to bar buttons, tab bars, segmented controls, and edit menus.

The lift effect combines a subtle parallax with the appearance of elevation to make an element seem like it's floating above the screen. As the pointer fades out beneath the element, iPadOS creates the illusion of lift by scaling the element up while adding a shadow below it and a soft specular highlight on top of it. By default, iPadOS applies the lift effect to app icons and to buttons in Control Center.

Hover is a generic effect that lets you apply custom scale, tint, or shadow values to an element as the pointer hovers over it. The hover effect combines your custom values to bring focus to an item, but it doesn't transform the default pointer shape.

I'm happy that Apple has regularly been updating their Human Interface Guidelines regularly as iOS changes. A lot has been said about the state of Apple's documentation, but fortunately the HIG seems to have great clarity and regular updates.

The additions that they made to the iOS HIG around pointers and putting names to the different interactive states of the new dynamic cursor in iPadOS is very helpful. Namely: highlight, lift and hover.

Most of the time I have been pretty happy with the new highlight and lift paradigms. In apps it feels great. In certain scenarios, such as the SpringBoard icon grid, all the lift effects across relatively large shapes feels like it captures or snags the cursor too much. I sometimes have the same problem in that situation that I do with tvOS selection: the parallax effect can be hard to notice and sometimes it makes it hard to find the current pointer location.

I'm definitely interested in seeing how this develops over time and the overall user reception of this. I also wonder if something similar could be brought to tvOS with a new remote.

@wooji on Twitter: Experiments with iPad OS 13.4 pointer animation…

I think there will be some interesting ways that cursors can provide extra context. I do worry that there might be too much experimentation here initially. I hope Apple works hard to enforce some level of consistency to avoid some of the odd custom pointer shapes that have shown up on a variety of websites.

Wednesday, March 18th 2020

iPadOS 13.4 And Cursors #

Apple iPad Pro

Apple: New Magic Keyboard Designed for iPad Pro Features a Floating Design, Backlit Keyboard and Trackpad, Delivering the Best Typing Experience Ever on iPad:

With iPadOS 13.4, Apple brings trackpad support to iPad, giving customers an all-new way to interact with their iPad. Rather than copying the experience from macOS, trackpad support has been completely reimagined for iPad. As users move their finger across the trackpad, the pointer elegantly transforms to highlight user interface elements. Multi-Touch gestures on the trackpad make it fast and easy to navigate the entire system without users ever lifting their hand.

Notably still absent from the keyboard: an ESC key.

The Verge: Here's how the iPad's new trackpad actually works:

We can answer some of your questions about how trackpad support will work today and we’ll get a chance to actually use it ourselves in the public beta. In the meantime, here’s what we definitely know about how it will work based on videos Apple has released publicly and on a video presentation given to reporters this morning.

  • The pointer will only appear when you need it. The mouse pointer won’t be persistent on the screen at all times, instead only appearing when you’re touching the trackpad.
  • The pointer is a little circular dot. Apple says that shape makes the most sense for the iPad, which again is fundamentally designed around touching with your fingers.
  • ...but it can change shape based on what it’s pointing at. You know how your desktop mouse pointer turns into a hand, text cursor, or a little resize arrow depending on what it’s pointing at? The iPad’s pointer does a similar thing. But since so many of the UI elements on the iPad are big, touchable buttons, the way the iPad cursor changes is a little different. It changes shape to be the size of the touch-target area for the button. (If the animations bug you, apparently you will be able to turn them off.)

It's really interesting how interactive controls capture and influence the appearance of the cursor. I'm going to hold off judgement until I have a chance to try it out with an external mouse. I hope it feels smoother than it looks. In some of the videos it looks like the cursor can get snagged or slowed as it passes over controls.

The New iPad Pro and Magic Keyboard with Trackpad: The MacStories Overview:

Along with the new iPad Pro, Apple also announced a new Magic Keyboard with trackpad specifically designed for the iPad Pro line. The Magic Keyboard ships in May, is available at $299 for the 11-inch iPad Pro and $349 for the 12.9-inch model, and will be backward-compatible with the 2018 iPad Pro line.

It looks amazing and is likely incredibly well designed, but $299–349 is a rough price tag.

According to Apple, most third-party apps will work with the new system-wide cursor (which, again, does not require the new Magic Keyboard) with no changes at all. However, there will be specific APIs for developers to fine-tune their apps’ UIs to the cursor (presumably, to better integrate with aspects such as hover states).

iOS is getting more and more complicated with every release and feature added. It's already really hard to justify the extra time to meet the minimum expectations for an iPadOS app as an independent developer. I hope the new default cursor system works pretty well with the standard UIButtons and UIControls without additional work.

Jason Snell:

Pro tablet without either of Apple's two big Pro apps. This needs to change.

I spend a majority of my professional time designing websites or apps and programming iOS apps. I certainly can't program iOS apps on an iPad and design tools aren't quite usable enough. The story with a lot of Apple products recently seems to be: the hardware is amazon, but the software isn't ready yet.

Even though I really enjoy iOS and the iPad, the unfortunate reality is that between the new iPad Pro or the new Macbook Air, the Macbook Air is the only device out of the two that I could actually do my job with. That might change in the near future, but doing my job on an iPad, regardless of cursor support, is currently not possible

Tim Horton:

Web Developers: The latest iOS 13.4 beta brings desktop-class pointer and mouse event support to Safari and WebKit on iPadOS! For best results, adopt Pointer events, and ensure that your web content does not /depend/ on touch events (which a trackpad or mouse will not send).

Steve Troughton-Smith:

You can add a UIPointerInteraction to your view, and its delegate will then be asked to provide a UIPointerRegion, and a UIPointerStyle for that region. A pointer style is an effect or shape, given a UIBezierPath, and can constrain movement in either axis (i.e. snap to regions)

Brandon Walkin:

Excited to share the new adaptive cursor and trackpad support for iPadOS.

It would be an absolute dream to be on the Apple HI team and work on this.

older home newer