Looking for a guide how to implement qr code scanner in Elixir/Phoenix app

Hello all, im looking for a post, link or tutorial where i can use Elixir/Phoenix to access devices camera and activate qrcode scanning. I want to add a feature on my system where it can scan qr codes. I hope someone can help me :pray:

1 Like

You can simply use zbarimg from Elixir. Here is an example article:

4 Likes

Thank you sir, i will look at it :pray:

I’m looking for a similar solution.
Liveview: People send in a form, they receive an email with qr code.

Couldn’t find a pure elixir solution.

Note: first day with elixir.

2 Likes

Hey @water Did you get any results with this?, I’m looking for a way to scan the qr and I’m testing this package but without success

@guibbv20111

I got it working with a plain Phoenix 1.7.2 app using LiveView.

mix phx.new --no-ecto qr_scanner
cd qr_scanner/assets
yarn add html5-qrcode
cd ..
iex -S mix phx.server

Add a route…

  scope "/", QrScannerWeb do
    pipe_through :browser

    get "/", PageController, :home

    live "/scanner", ScannerLive
  end

Creat the LiveView…

defmodule QrScannerWeb.ScannerLive do
  use QrScannerWeb, :live_view

  def mount(_params, _session, socket) do
    {:ok, socket}
  end

  def handle_event("qr-code-scanned", params, socket) do
    {:noreply, socket}
  end

  def render(assigns) do
    ~H"""
    <div id="reader" width="600px" phx-hook="Scanner"></div>
    """
  end
end

Then add a hook in app.js.

import { Html5QrcodeScanner } from "html5-qrcode"

let Hooks = {}

Hooks.Scanner = {
  onScanFailure(error) {
  },

  mounted() {
    let html5QrcodeScanner = new Html5QrcodeScanner(
      "reader",
      { fps: 10, qrbox: { width: 250, height: 250 } },
      false
    );
    onScanSuccess = (decodedText, decodedResult) => {
      this.pushEvent("qr-code-scanned", decodedResult);
    }
    html5QrcodeScanner.render(onScanSuccess, this.onScanFailure);
  }
}

let csrfToken = document.querySelector("meta[name='csrf-token']").getAttribute("content")
let liveSocket = new LiveSocket("/live", Socket, { params: { _csrf_token: csrfToken }, hooks: Hooks })

When you load the page in a browser, it will ask for camera permissions. Hit yes, scan your QR code and you should see something like this your Phoenix logs:

[debug] HANDLE EVENT "qr-code-scanned" in QrScannerWeb.ScannerLive
  Parameters: %{"decodedText" => "https://www.coautilities.com/go/paperless", "result" => %{"debugData" => %{"decoderName" => "zxing-js"}, "format" => %{"format" => 0, "formatName" => "QR_CODE"}, "text" => "https://www.coautilities.com/go/paperless"}}
[debug] Replied in 832µs
4 Likes

Well, the same code didn’t work for me, maybe my version is the problem :thinking:, I’ll try it here and return the result later

Thanks in advance

I had a similar problem and decided to go with Rustler since I find zbar not that reliable.

 {:rustler, "~> 0.27.0"},

then used the following libraries on the Rust side

[dependencies]
rustler = "0.27.0"
bardecoder = "0.4.0"
image = "0.23"
imageproc = "0.22.0"

Unfortunately, I can’t share the code here but I got very good (and fast) results with this combination. I also learned some Rust which was fun. Though, in my case I am actually looking for QR codes in scanned images which is a bit different.

The HTML5 solution looks interesting.

1 Like

I literally just make a Rustler package today!

I know it’s off topic, but wow… my socks were blown off by how easy Rustler is to use.

1 Like

After upgrading Elixir/Erlang and Phoenix/Liveview, this works great