Michael Schmitt

Software Developer in Illinois

Extracting colors from images for pre-loading, iOS 15 Safari, and more

· 06/19/2021 · python ·

Using calculated colors in iOS 15 Safari

A constant challenge for image-rich applications, whether mobile apps or website, is what to display while images are loading. There's plenty of options, but one that grabbed my attention recently was BlurHash - a library that displays blurred representations of a image using a short string while hte larger asset is loading.

I really liked this idea, but wanted to find a way to replicate a similar experience in Serial Reader without depending on a library. Plus, because all the book images in Serial Reader are pretty much a single color, a much simpler strategy would likely be good enough.

After some experimentation, I landed on this approach:

  1. Open the original image
  2. Apply a ridiculous gaussian blur with a radius of 3x the image's width
  3. Get the color at the first pixel of the blurred image (bonus: convert this rgb value to a hex for easier web use)

Here's an example implementation of the above using Python and PIL:

  from io import BytesIO
  from PIL import Image, ImageFilter

  original_image = Image.open(image_filepath).convert("RGB")
  image_width = original_image.size[0]
  blurred_image = im1.filter(ImageFilter.GaussianBlur(radius = image_width * 3))
  buffered = BytesIO()
  blurred_image.save(buffered, format="PNG")
  r, g, b = blurred_image.getpixel((1, 1))

Essentially this flattens an image to its most basic color. I then save this color value as a hex string alongside other metadata for each book so it can be easily provided and used as a placeholder while the book image itself loads.

In Serial Reader's iOS and Android apps, I can use this hex color as the background color for each image which is overwritten by the real image when it loads. It results in a nice morph effect that isn't too distracting but a step beyond whitespace or a loading animation.


iOS 15 Safari

Now that I have this handy color value, dynamically generated per book image, there are some other fun things I can do. For example, I can set the image border to this color even after the image has loaded for a subtle pop. I can also lean on these colors to customize the feel of Safari in iOS 15.

Each book in Serial Reader has its own dedicated page on the website, so for each I can pass through the hex color value as a meta "theme-color" value.

 <meta name="theme-color" content="#{{ book.image_color }}">

In iOS 15, Safari then updates its UI to match each book's image.



Previous Next
Migrating a MongoBD replica set to a new hosting provider with no downtime Book Report: "The War of the Poor" by Éric Vuillard
Linode: Lightning-Quick SSD Servers for Only $5/mo »