Blurhash (blurhash v0.1.0)
Blurhash
A pure Elixir implementation Blurhash decoder/encoder.
Documentation: https://hexdocs.pm/rinpatch_blurhash
Installation
Add Blurhash to your mix.exs:
def deps do
[
{:rinpatch_blurhash, "~> 0.1.0"}
]
endIf you would like to use the downscale_and_decode/3 function, you also need to add Mogrify:
def deps do
[
{:rinpatch_blurhash, "~> 0.1.0"},
{:mogrify, "~> 0.8.0"}
]
endUsage
Encoding
The algorithm authors recommend to downscale the image to 32-20 pixels in width before encoding the blurhash, this will make encoding faster while leading to a similar-looking result. If ImageMagick is available on your system, you can simply add Mogrify package to your dependencies and use downscale_and_encode/3:
path = "/tmp/lenna.png"
components_x = 4
components_y = 3
{:ok, blurhash} = Blurhash.downscale_and_encode(path, components_x, components_y)Be aware that this function uses a port and has no rate limiting or pooling. If a large number of blurhashes needs to be encoded at the same time, use an external solution to limit it, such as a job queue.
If you already have a thumbnail to encode to a blurhash, the encode/5 function accepts a raw 8-bit RGB binary along with it's width and height.
Here is how to convert an image to raw pixels using imagemagick:
convert lenna.png -depth 8 lenna.rgbThen you can use it like this:
lenna = File.read!("lenna.rgb")
width = 512
height = 512
components_x = 4
components_y = 3
{:ok, blurhash} = Blurhash.encode(lenna, width, height, 4, 3)Decoding
The decode/3 functions accepts a blurhash, as well as the width and height of the result image. The output is 8-bit raw RGB binary and the average colour of the image as an {r, g, b} tuple.
For example, decoding a blurhash to a 32x32 image:
blurhash = "LELxMqDQNE}@^5=aR6N^v}ozEh-n"
width = 32
height = 32
{:ok, pixels, {r, g, b} = average_color} = Blurhash.decode(blurhash, width, height)decode_to_iodata/3 function is the same as decode/3, except it returns iodata instead of a binary. This is useful if you are writing the raw pixels to a file or a socket later.
For example, decoding a blurhash, writing the raw pixels to a file and converting it to a jpg using Mogrify:
blurhash = "LELxMqDQNE}@^5=aR6N^v}ozEh-n"
width = 32
height = 32
{:ok, pixels_iodata, {r, g, b} = average_color} = Blurhash.decode(blurhash, width, height)
decoded_raw_path = "lenna_blurhash.rgb"
File.write!(decoded_raw_path, pixels_iodata)
%{path: decoded_jpg_path} =
Mogrify.open(decoded_raw_path) |> Mogrify.custom("size", "#{width}x#{height}") |> Mogrify.custom("depth", "8")|> Mogrify.format("jpg") |> Mogrify.save()
Link to this section Summary
Functions
Decode a blurhash. Returns raw pixels (8bit RGB) and average color.
Same as decode/3, except returns pixels as iodata.
Downscale the image using &downscale_image/1 and encode a blurhash for it.
Downscale the image to 32 pixels wide and convert it to raw pixels, making it ready for Blurhash encoding. Returns path to image, width and height in case of success. Requires Mogrify package and ImageMagick to be installed on the system.`
Encodes a blurhash from raw pixels (8bit RGB).
Link to this section Types
blurhash()
Specs
blurhash() :: String.t()
color()
Specs
color() :: {0..255, 0..255, 0..255}
pixels()
Specs
pixels() :: <<_::8>>
pixels_iodata()
Specs
pixels_iodata() :: pixels() | [pixels() | pixels_iodata()]
Link to this section Functions
decode(blurhash, width, height)
Specs
decode(blurhash(), pos_integer(), pos_integer()) :: {:ok, pixels(), color()} | {:error, :unexpected_components | :unexpected_end}
Decode a blurhash. Returns raw pixels (8bit RGB) and average color.
decode_to_iodata(blurhash, width, height)
Specs
decode_to_iodata(String.t(), pos_integer(), pos_integer()) :: {:ok, pixels_iodata(), color()} | {:error, :unexpected_components | :unexpected_end}
Same as decode/3, except returns pixels as iodata.
downscale_and_encode(path, components_x, components_y)
Specs
downscale_and_encode(Path.t(), pos_integer(), pos_integer()) :: {:ok, blurhash()} | {:error, any()}
Downscale the image using &downscale_image/1 and encode a blurhash for it.
downscale_image(path)
Specs
downscale_image(Path.t()) :: {:ok, Path.t(), pos_integer(), pos_integer()} | {:error, any()}
Downscale the image to 32 pixels wide and convert it to raw pixels, making it ready for Blurhash encoding. Returns path to image, width and height in case of success. Requires Mogrify package and ImageMagick to be installed on the system.`
encode(pixels, width, height, components_x, components_y)
Specs
encode(pixels(), pos_integer(), pos_integer(), 1..9, 1..9) :: {:ok, blurhash()} | {:error, :too_many_components | :too_little_components | :malformed_pixels}
Encodes a blurhash from raw pixels (8bit RGB).