Media

BlurHash

A photo as a short BlurHash, shown blurred while the real one loads, and back as a small PNG data URL.

Version 1.0.0 · 2 functions · 3 crates

#images#placeholders#performance

Functions

What use blurhash.qwer gives a program, with the types Quillo sees. To take only some, or under other names: use blurhash_of, blurhash_data_url from blurhash (Quillo 0.6).

blurhash_of(path: str) → stror an error

The BlurHash of the image at path (JPEG, PNG, WebP or GIF), with 4 by 3 components: store it beside the photo.

blurhash_data_url(hash: str, width: int, height: int) → stror an error

A small PNG of a BlurHash, as a data: URL for an <img> or a CSS background: width by height pixels (32 by 32 is plenty; CSS scales it).

Get it

$ quillo install blurhash               # blurhash.qwer into this folder$ quillo install blurhash --example     # and its example, blurhash.qwe

Or with curl:

$ curl -O https://quillolang.org/plugins/files/blurhash.qwer$ curl -O https://quillolang.org/plugins/files/blurhash.qwe$ curl -O https://quillolang.org/plugins/files/sample.jpg

Then, in your program, all of it or only what you call:

main.qwe
use blurhash.qweruse blurhash_of, blurhash_data_url from blurhash      // Quillo 0.6: only these

It uses these crates, which cargo fetches the first time the plugin is built:

[dependencies]
blurhash = "0.2"image = { version = "0.25", default-features = false, features = ["jpeg", "png", "webp", "gif"] }base64 = "0.22"

Example

blurhash.qwe
// A photo that shows blurred until it has loaded.////   quillo run blurhash.qwe      then open http://localhost:8080/   (sample.jpg beside it)use "blurhash.qwer"let hash = blurhash_of("sample.jpg")?route GET /sample.jpg = file("sample.jpg")route GET /hash = { hash }route GET / = <html><body>    <img src="/sample.jpg" width="480" height="252" alt="The Quillo banner"         style={`background: url(${blurhash_data_url(hash, 32, 17)?}) center / cover`}/></body></html>
$ quillo run blurhash.qwe$ curl 'localhost:8080/hash'$ curl 'localhost:8080/'

Source

blurhash.qwer
//! BlurHash placeholders: a photo as 20-odd characters that a page shows blurred while the real one loads.//! version: 1.0.0//!//! [dependencies]//! blurhash = "0.2"//! image = { version = "0.25", default-features = false, features = ["jpeg", "png", "webp", "gif"] }//! base64 = "0.22"use base64::engine::general_purpose::STANDARD;use base64::Engine;/// The BlurHash of the image at `path` (JPEG, PNG, WebP or GIF), with 4 by 3 components: store it beside the photo.pub fn blurhash_of(path: &str) -> Result<String, String> {    let img = image::open(path).map_err(|e| format!("{}: {}", path, e))?.thumbnail(64, 64).to_rgba8();    blurhash::encode(4, 3, img.width(), img.height(), img.as_raw()).map_err(|e| format!("{:?}", e))}/// A small PNG of a BlurHash, as a `data:` URL for an `<img>` or a CSS background: `width` by `height` pixels (32 by 32 is plenty; CSS scales it).pub fn blurhash_data_url(hash: &str, width: i64, height: i64) -> Result<String, String> {    let (w, h) = (width.clamp(4, 256) as u32, height.clamp(4, 256) as u32);    let pixels = blurhash::decode(hash, w, h, 1.0).map_err(|e| format!("{:?}", e))?;    let img = image::RgbaImage::from_raw(w, h, pixels).ok_or("the hash did not decode")?;    let mut png = std::io::Cursor::new(Vec::new());    img.write_to(&mut png, image::ImageFormat::Png).map_err(|e| e.to_string())?;    Ok(format!("data:image/png;base64,{}", STANDARD.encode(png.into_inner())))}
Thread
76Useful? Like it, or add to its thread below.

Thread 0 posts

On BlurHash: questions, tips, corrections, and code that uses it.

No posts yet. The first one opens the thread.