ターミナルでQRコードを表示してURL共有する方法まとめ【Python / qrencode / Node.js・WSL対応】

先日の投稿でCloudflare Quick TunnelsでローカルアプリをURL公開する記事を書きました。

前回の記事

uepon.hatenadiary.com

その中で、生成されたURLをQRコードのPNGファイルとして保存するところまでやったのですが、実際使ってみると「QRコード画像ファイルをわざわざ開くのがかなり面倒」という問題がありました。

WSLのターミナルで作業しているのに、QRコードを見せるためにWindowsのエクスプローラーでPNGを探して開いて…って作業をするのは結構面倒😫

QRコードが生成されたらターミナル上に表示して、そのままスマホで読み取るだけでいいのでは?

ということで、コンソール上でQRコードを表示する方法を調べて、前回のツールに組み込んでみました。

コンソールでQRコードを表示する方法

調べてみると、いくつかの方法がありました。

1. qrencode コマンド(Linuxコマンド)

まずは、Linuxで使える定番のQRコード生成コマンドとなります。

$ sudo apt install qrencode
$ qrencode -t UTF8 "https://example.com"

-t UTF8オプションを指定するとUnicodeのブロック文字(█ ▀ ▄ など)を使ってターミナルに直接描画してくれます。他にも -t ANSI-t ANSI256 などの出力形式があるようです。テキストからQRコードを生成して表示するだけなら、これが最もシンプルですね。標準出力にリダイレクトするといったプログラムであれば、ワンライナーで済ませることもできます。

また、WSLで実行できるコマンドはPowerShellでも動作させることができます。以下のように実行することで、いつでも実行ができます。 以下の例ではWSLのディストリビューション名をMyUbuntuとしています。自分の環境にあわせることで簡単に動作ができます。

PS> wsl -d MyUbuntu qrencode -t UTF8 "https://example.com"

ただ今回はPythonのプログラムに組み込みたかったので、別の方法を選びました。

2. Python qrcode ライブラリの print_ascii()

前回のスクリプトでもQRコード画像の生成に使っていた qrcode ライブラリですが、実は ターミナルへのテキスト出力機能も持っています。

# ライブラリのインストールが必要です→ pip install "qrcode[pil]"
import qrcode

qr = qrcode.QRCode(border=1)
qr.add_data("https://example.com")
qr.make(fit=True)
qr.print_ascii(invert=True)

これだけでターミナルにQRコードが表示されます。invert=True を指定すると白黒が反転して、ターミナルの暗い背景でも読み取りやすくなります。

前回のプログラムからであれば、追加のライブラリが不要で、すでに使っている qrcode だけで完結するのがポイントです。

3. Node.js qrcode-terminal

Node.js環境であれば qrcode-terminal もあります。

$ npx qrcode-terminal "https://example.com"

Node.js系のアプリと組み合わせるときは、こちらの方が相性が良いかもしれません。

どれを選ぶか?

今回はPythonのqrcodeライブラリの print_ascii()を採用しました。理由は次の通りです。

  • 前回のプログラムで qrcode ライブラリを使っているので、追加インストールが不要
  • Pythonのコード内で制御できるので、URL取得後のタイミングで自然に呼び出せる

Pythonプログラムへの組み込み

前回のスクリプト(cloudflared_tunnel.py)に対して、変更は2箇所だけです。

1. display_qr_in_terminal 関数の追加

今回使用するQRコードのターミナル表示用の関数を追加します。これは比較的他のプロジェクトでも使い回せる汎用的な関数ですね。

def display_qr_in_terminal(url):
    """QRコードをターミナルにテキストで表示"""
    try:
        qr = qrcode.QRCode(
            border=1,
            error_correction=qrcode.constants.ERROR_CORRECT_L,
        )
        qr.add_data(url)
        qr.make(fit=True)
        print("📱 スマホでスキャンしてください:")
        print()
        qr.print_ascii(invert=True)
        print()
    except Exception as e:
        print(f"⚠️ ターミナルへのQRコード表示に失敗しました: {e}")

この処理のポイントは以下となります。

  • border=1 でQRコードの余白を小さめにし、ターミナルでの表示をコンパクトにしている
  • invert=True で白黒反転。WSLのデフォルトの暗い背景でも読み取りやすくなる
  • error_correction=ERROR_CORRECT_L で誤り訂正レベルをLow(7%)に設定。URLのような短いデータでは十分で、QRコードのサイズが小さくなる
  • try-except で囲んでいるので、万が一表示に失敗してもスクリプト全体は止まらない

2. main 関数内での呼び出し

    # QRコードを生成(PNGファイル)
    generate_qr_code(tunnel_url, qr_file_path)
    
    # QRコードをターミナルに表示 ← ここを追加
    display_qr_in_terminal(tunnel_url)

PNG画像の生成の直後に、ターミナル表示を呼び出すだけです。

実行結果

実際に追加したコードを実行すると、以下のような出力がターミナルに表示されました。

このターミナル画面をそのままスマホのカメラで読み取るだけ。わざわざPNG画像を開く必要がないので楽になりました🤩

フォントの問題

QRコードの表示にはUnicodeのブロック文字(█ ▀ ▄)を使っています。ターミナルのフォントがこれらの文字をサポートしていないと、表示が崩れます。

Windows Terminalを使っている場合はデフォルトのCascadia Monoで問題なく表示できます。もし崩れる場合は等幅フォントに変更すると改善のではないでしょうか。

ターミナルの幅が足りない

QRコードはURLの長さに応じてサイズが変わります。Cloudflare Quick Tunnelsの生成URLは結構長い(https://xxxx-xxxx-xxxx-xxxx.trycloudflare.com)ので、ターミナルの幅が狭いと折り返されて読み取れなくなります。そんなときにはターミナルの幅を80カラム以上にしておくのが無難です。

qrencode コマンドも便利

スクリプトに組み込む用途では Python の qrcode ライブラリが便利でしたが、コマンドラインからさっとQRコードを表示したいだけなら qrencode コマンドもおすすめです。こちらはワンライナーで完結するので、ちょっとしたURL共有のときに便利ですね。

$ sudo apt install qrencode

# URLをQRコード表示
$ qrencode -t UTF8 "https://example.com"

# .bashrcにエイリアスを追加しておくと楽
$ echo 'qr() { qrencode -t UTF8 "$1"; }' >> ~/.bashrc
$ source ~/.bashrc

# 以後はこれだけ
$ qr "https://example.com"

デモや発表の場で「このURLにアクセスしてください」と言いながら、ターミナルで qr "URL" を叩くだけでQRコードが出る…というのはなかなかスマートです。

おわりに

コンソールにQRコードを表示するというのは、調べてみると意外と簡単にできました。PNGファイルとして保存する仕組みはすでにあったので、ターミナル表示を追加したのは実質10行程度です。

以前は、Google ChromeのQRコード生成機能や、QRコードを生成するGoogle Colabノートブックを用意してURLをコピペして…という流れでしたが、これがターミナル上で完結するようになったので便利になりました。

GoogleColabノードブックでの参考例

uepon.hatenadiary.com

WSLのbashターミナル上でも問題なく動作する点がいいですね🤗🤗🤗