Skip to content

elixir-image/image_qrcode

Repository files navigation

Image.QRCode

QR code encoding and decoding for the Image library, implemented as a NIF over two small, well-regarded C libraries:

Both libraries are vendored under c_src/ and statically linked into the NIF, so the package has no system-library dependencies beyond a C compiler on platforms where a precompiled artefact is not available.

The standard image type for both input and output is t:Vix.Vips.Image.t/0. Conversion to and from the raw module / grayscale buffers required by the underlying C libraries is performed implicitly.

Installation

Add :image_qrcode to your mix.exs dependencies:

def deps do
  [
    {:image_qrcode, "~> 0.1"}
  ]
end

Toolchain

Both image_qrcode and its :vix dependency ship as precompiled NIFs on the common targets, so no C toolchain is required on:

  • macOS (x86_64, arm64)
  • Linux x86_64, aarch64 (gnu and musl), armv7-gnu
  • Windows x86_64 (MSVC)

On any other target, or if the precompiled artefact download fails, mix deps.compile falls back to building from the vendored sources. In that case a C11 compiler and make are required. (:vix bundles its own copy of libvips as part of its precompile, so installing libvips system-wide is not necessary either.)

Usage

Encoding

Image.QRCode.encode/2 takes a string and returns a single-band 8-bit t:Vix.Vips.Image.t/0 rendering of the QR code:

{:ok, image} = Image.QRCode.encode("https://example.com")
:ok = Vix.Vips.Image.write_to_file(image, "qr.png")

Common options:

  • :ecc:low | :medium | :quartile | :high (default :medium).
  • :scale — pixels per QR module (default 4).
  • :quiet — quiet-zone width in modules (default 4, the QR spec minimum).
  • :version_min / :version_max — bounds for the QR version (1..40).
  • :mask:auto (default) or an integer 0..7.
  • :boost_ecc — let the encoder upgrade ECC if the chosen version has spare capacity (default true).

Decoding

Image.QRCode.decode/1 takes any t:Vix.Vips.Image.t/0 and returns a list of decoded QR codes. The image is implicitly converted to grayscale, so RGB, RGBA, float-format and multi-band inputs are all accepted:

{:ok, image} = Vix.Vips.Image.new_from_file("qr.png")
{:ok, [%{payload: payload, version: version, corners: corners}]} =
  Image.QRCode.decode(image)

Each decoded entry is a map with :payload, :version, :ecc_level, :mask, :data_type, :eci and :corners (the four corners of the code in image coordinates, top-left clockwise).

Concurrency

Both encoder and decoder hold no shared mutable state — each call allocates its own scratch buffers — and the NIF is scheduled on dirty CPU schedulers, so concurrent invocation from many processes is safe and parallelised. A stress harness (test/concurrency_test.exs, tagged :concurrency) verifies this property by running 500 round-trips at high concurrency.

License

This library is released under the Apache-2.0 license. The vendored encoder is MIT-licensed (Nayuki) and the vendored decoder is ISC-licensed (Daniel Beer); their license headers are retained in the source tree under c_src/nayuki and c_src/quirc.

About

Elixir NIF-based qrcode writer and scanner

Resources

License

Stars

Watchers

Forks

Packages

 
 
 

Contributors