Storehouse.Analyzer.Placeholder (Storehouse v0.2.0)

Copy Markdown View Source

A step (Storehouse.Analyzer) that makes what a page shows while a photograph loads, under "placeholder":

  • "placeholder" - a tiny version of it, a few hundred bytes, as a data URI the browser stretches into a soft blur: a <img>'s background, or React's placeholder.
  • "color" - its average colour, #rrggbb, painted under it.
  • "width" and "height" - the tiny version's, its proportions.
# mix.exs: libvips, through Vix.
{:vix, "~> 0.31"}

Storehouse.store(upload.path, analyze: [Storehouse.Analyzer.Placeholder])

It is made with libvips, shrinking as it loads: a 6000 × 4000 JPEG is decoded at an eighth of its size or less, never whole, in about 150 ms where decoding it whole takes 260, and a few kilobytes past what the decoder holds. It is turned as its EXIF says, in sRGB. A file libvips does not read (one that is not an image; HEIC, where libvips is built without its codec) is skipped, or fails the step, with why: the photograph still shows, on its page's ground.

Options

  • :size - the longest edge, in pixels. The default is 16: larger is sharper, and heavier.
  • :format - :webp (the default), :jpeg or :png.
  • :quality - 1 to 100, for WebP and JPEG. The default is 40.
  • :background - "#rrggbb": a photograph with transparency is laid on it, and its colour taken so. The default keeps its transparency (in WebP and PNG; JPEG has none, and is laid on white).

In a page

<img src={@photo.url} width={@photo.width} height={@photo.height}
     style={"background: #{analyzed.color} url(#{analyzed.placeholder}) center / cover"} />

and in JSON, for a React <img> (Storehouse.File.to_map(file, analysis: [:placeholder])).

For a frontend that decodes a hash instead, Storehouse.Analyzer.ThumbHash and Storehouse.Analyzer.BlurHash.