Packages
image
0.54.4
0.72.0
0.71.0
0.70.0
0.69.0
0.68.0
0.67.0
0.67.0-dev
retired
0.66.0
0.65.0
0.64.0
0.63.0
0.62.1
0.62.0
0.61.1
0.61.0
0.60.0
0.59.3
0.59.2
0.59.1
0.59.0
0.58.0
0.57.0
0.56.1
0.56.0
0.55.2
0.55.1
retired
0.55.0
0.54.4
0.54.3
0.54.2
0.54.1
0.54.0
0.53.0
0.52.3
0.52.2
0.52.1
0.52.0
retired
0.51.0
0.50.0
0.49.0
0.48.1
0.48.0
0.47.0
0.46.0
0.45.0
0.44.0
0.43.2
0.43.1
0.43.0
0.42.0
0.41.0
0.40.0
0.39.3
0.39.2
0.39.1
0.39.0
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.0
0.36.2
0.36.1
0.36.0
0.35.0
0.34.0
0.33.0
0.32.0
0.31.1
0.31.0
0.30.0
0.29.0
0.28.2
0.28.1
0.28.0
0.27.0
0.26.0
0.25.1
0.25.0
0.24.1
0.24.0
0.23.2
0.23.1
0.23.0
0.22.1
0.22.0
0.21.0
0.20.0
retired
0.19.0
0.18.1
0.18.0
0.17.0
0.16.0
0.15.0
0.14.4
0.14.2
0.14.1
0.14.0
retired
0.13.1
0.13.0
0.12.0
0.11.0
0.10.0
0.10.0-rc.0
retired
0.9.0
retired
0.8.0
0.7.0
0.6.0
0.5.0
0.4.0
0.3.0
0.2.0
0.1.0
An approachable image processing library primarily based upon Vix and libvips that is NIF-based, fast, multi-threaded, pipelined and has a low memory footprint.
Current section
Files
Jump to
Current section
Files
lib/image/blurhash.ex
defmodule Image.Blurhash do
@moduledoc """
BlurHash is an algorithm developed by [Wolt](https://github.com/woltapp)
that allows encoding of an image into a compact string representation
called a blurhash. This string can then be decoded back into
an image, providing a low-resolution placeholder that can be
displayed quickly while the actual image is being loaded.
It combines the benefits of data compression and perceptual
hashing to create visually pleasing representations of images.
The blurhash string consists of a short sequence of characters
that represents the image's colors and their distribution. By
adjusting the length of the blurhash, you can control the level
of detail and the amount of data required to represent the image.
The encode and decoder in this implementation are a fork of
the [rinpatch_blurhash](https://github.com/rinpatch/blurhash) library
by @rinpatch.
"""
alias Vix.Vips.Image, as: Vimage
@doc """
Encodes an image as a [blurhash](https://blurha.sh).
`Image.Blurhash.encode/2` takes an image and returns a short string
(only 20-30 characters) that represents the placeholder
for this image.
It is intended that calculating a blurhash is performed
in a background process and stored for retrieval on demand
when rendering a page.
### Arguments
* `image` is any `t:Vix.Vips.Image.t/0`. Only 3-band images
are supported by blurhash. Therefore if `image` has an
alpha band it is necessary to flatten `image` or remove the
alpha band before calling `Image.Blurhash.encode/2`.
* `options` is a keyword list of options. The default is
`[x_components: 4, y_components: 3]`.
### Options
* `:x_components` represents the number of horizontal blocks used
to calculate the blurhash.
* `:y_components` represents the number of vertical blocks used
to calculate the blurhash.
### Returns
* `{:ok, blurhash}` or
* `{:error, reason}`
### Selecting the number of X and Y components
A higher `:x_components` and `:y_components` value will result in
more details in the blurhash in the X and Y direction respectively.
A lower value will create a more abstract representation.
By adjusting the X and Y components, you can control the level of
granularity and complexity in the generated blurhash. However, it's
important to note that increasing the X and Y values also increases
the size of the blurhash string, which may impact performance and
bandwidth usage.
The default of `[x_components: 4, y_components: 3]` is a good starting
points but if the the image aspect ratio is portrait, a higher
`:y_compnents` value may be appropriate.
### Example
iex> image = Image.open!("./test/support/images/Kip_small.jpg")
iex> Image.Blurhash.encode(image)
{:ok, "LBA,zk9F00~qofWBt7t700%M?bD%"}
"""
@doc subject: "Operation", since: "0.44.0"
@spec encode(image :: Vimage.t(), options :: Keyword.t()) ::
{:ok, String.t()} | {:error, Image.error_message()}
def encode(%Vimage{} = image, options \\ []) do
with {:ok, options} <- Image.Options.Blurhash.validate_options(image, options),
{:ok, binary} <- Vimage.write_to_binary(image) do
{width, height, _bands} = Image.shape(image)
Image.Blurhash.Encoder.encode(
binary,
width,
height,
options.x_components,
options.y_components
)
end
end
@doc """
Decodes an blurhash to an image.
### Arguments
* `blurhash` is a blurhash returned by `Image.Blurhash.encode/2`.
* `width` is the required width of the returned image.
* `height` is the required height of the returned image.
### Returns
* `{:ok, image}` or
* `{:error, reason}`
### Examples
iex> image = Image.open!("./test/support/images/Kip_small.jpg")
iex> {:ok, blurhash} = Image.Blurhash.encode(image)
iex> {:ok, _image} = Image.Blurhash.decode(blurhash, 400, 200)
iex> Image.Blurhash.decode("nonsense", 400, 200)
{:error, "Invalid blurhash"}
"""
@bands_in_blurhash 3
@blurhash_band_format :VIPS_FORMAT_UCHAR
@doc subject: "Operation", since: "0.44.0"
@spec decode(blurhash :: String.t(), width :: pos_integer(), height :: pos_integer()) ::
{:ok, Vimage.t()} | {:error, Image.error_message()}
def decode(blurhash, width, height)
when is_binary(blurhash) and is_integer(width) and is_integer(height) and width > 0 and
height > 0 do
with {:ok, pixel_iodata, _average_color} <-
Image.Blurhash.Decoder.decode(blurhash, width, height) do
pixel_binary = IO.iodata_to_binary(pixel_iodata)
Vix.Vips.Image.new_from_binary(
pixel_binary,
width,
height,
@bands_in_blurhash,
@blurhash_band_format
)
end
end
end