Packages
image
0.25.0
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/qrcode.ex
if Image.evision_configured?() do
defmodule Image.QRcode do
@moduledoc """
Detects and decodes QRcodes.
Note that the implementation, which is based upon
[eVision](https://github.com/cocoa-xu/evision) requires that
the image be a 3-channel image in order to support
detection.
Images that are in different formats must be converted
first.
### Note
This module is only available if the optional dependency
[eVision](https://hex.pm/packages/evision) is configured in
`mix.exs`.
"""
alias Vix.Vips.Image, as: Vimage
alias Evision.QRCodeDetector, as: Detector
alias Evision.QRCodeEncoder, as: Encoder
import Detector, only: [qrCodeDetector: 0]
@dialyzer {:nowarn_function, {:decode, 1}}
@doc """
Encodes a string as a QRCode.
### Arguments
* `string` is any string to be encoded,
* `options` is a keyword list of options. The
default is `size: :auto`.
## Options
* `:size` is the size in pixels of the QRcode
dimensions. The default is `:auto` in which
the generated QRcode will be the minimum dimensions
necessary to encode the `string`.
### Returns
* `{:ok, image}` or
* `{:error, reason}`
"""
@doc since: "0.13.0"
def encode(string, options \\ []) when is_binary(string) do
size = Keyword.get(options, :size, :auto)
with %Evision.Mat{} = mat <- Encoder.encode(Encoder.create(), string) do
case size do
:auto ->
Image.from_evision(mat)
size when is_integer(size) and size > 0 ->
{:ok, image} = Image.from_evision(mat)
scale = scale_from_size(image, size)
Image.resize(image, scale, interpolate: :nearest)
other ->
{
:error,
"Invalid `:size` option. `:size` must be a positive " <>
"integer or `:auto`. Found #{inspect(other)}."
}
end
end
end
defp scale_from_size(image, size) do
width = Image.width(image)
max(size / width, 1)
end
@doc """
Detects and decodes a QR code in an image.
### Arguments
* `image` is any `t:Vix.Vips.Image.t/0` that
has three bands (for example, a typical srgb
image).
### Returns
* `{:ok, string}` or
* `{:error, reason}`
### Note
Only images with three bands (channels) are
supported. This restriction may be lifted in
a future release.
"""
@doc since: "0.9.0"
def decode(%Vimage{} = image) do
with {:ok, evision} <- Image.to_evision(image) do
decode(evision)
end
end
# The QRcode encoder will encode the smallest possible image
# as a result, its often not recognised by the decoder. So we
# resize to a minimum size. Sizes less than 300px do not
# reliably decode (based upon informal testing).
@minumum_dimension 300
@dimensions {@minumum_dimension, @minumum_dimension}
def decode(%Evision.Mat{shape: {height, width, _}} = evision)
when height < @minumum_dimension or width < @minumum_dimension do
resized =
Evision.resize(evision, @dimensions, interpolate: Evision.Constant.cv_INTER_NEAREST())
decode(resized)
end
def decode(%Evision.Mat{} = evision) do
case Detector.detectAndDecode(qrCodeDetector(), evision) do
{string, %Evision.Mat{} = _points, %Evision.Mat{} = _rectified} ->
{:ok, string}
{"", %Evision.Mat{}, {:error, "empty matrix"}} ->
{:error, "QRcode detected but could not be decoded"}
{"", {:error, "empty matrix"}, {:error, "empty matrix"}} ->
{:error, "No QRcode detected in the image"}
end
end
end
end