0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Next.js+supabaseで商品成分サーチアプリを作ってみた話2(バーコードリーダー)

Last updated at Posted at 2024-09-09

※初心者のため、間違いや何かご存じの方がいましたら、教えていただけると助かります。

作ったもの

概要

今回のアプリで、typescriptで使えるバーコードリーダーライブラリとして、Quagga.jsとZXingが候補に挙がった。
どちらを使うか。

環境

windows11
docker-desktop
Next.js(app routerを使用)
supabase
ホスティング:Vercel

内容

以下は、BingAIにまとめてもらった表。

特徴 Quagga.js ZXing
言語 JavaScript Java, JavaScript, C++, C#, Objective-C, Python, Rust, etc.
対応バーコード EAN, Code 128, Code 39, Interleaved 2 of 5, UPC, etc. QR Code, Data Matrix, Aztec, PDF 417, EAN, UPC, Code 128, etc.
ブラウザ対応 はい はい
モバイル対応 はい はい
ライセンス MIT License Apache License 2.0
ドキュメント 比較的少ない 豊富
パフォーマンス 高速だが、特定のバーコードに最適化されている 幅広いバーコードに対応しており、全体的に高性能
コミュニティ 活発だが、ZXingほど大きくはない 非常に活発で広範囲
使用例 ウェブアプリケーションでのバーコードスキャン モバイルアプリケーション、デスクトップアプリケーション、ウェブアプリケーション

Quaggaは高速だが、1Dコードしか対応していない。
ZXingは少し遅い?が、2Dコード(QRコード)にも対応。

各コード例(components/BarcodeScanner.tsx)

Quagga.js(今回、Quaggaは、以下のコードではうまく動かなかった。ビデオは起動するが、読み取ってくれない。原因までわからず。)

import Quagga from "quagga";
import { useEffect, useRef, useState } from "react";

interface BarcodeScannerProps {
    onScan: (code: string) => void;
}

const BarcodeScanner: React.FC<BarcodeScannerProps> = ({ onScan }) => {
    const [scanning, setScanning] = useState(false);
    const videoRef = useRef<HTMLVideoElement>(null);

    useEffect(() => {
        if (scanning) {
            Quagga.init(
                {
                    inputStream: {
                        type: "LiveStream",
                        target: videoRef.current,
                        constraints: {
                            facingMode: "environment",
                        },
                    },
                    decoder: {
                        readers: [
                            "code_128_reader",
                            "ean_reader",
                            "ean_8_reader",
                            "code_39_reader",
                            "code_39_vin_reader",
                            "codabar_reader",
                            "upc_reader",
                            "upc_e_reader",
                            "i2of5_reader",
                        ],
                    },
                },
                (error: any) => {
                    if (error) {
                        console.log(error);
                        setScanning(false);
                        return;
                    }
                    Quagga.start();
                }
            );
        }

        return () => {
            if (scanning) {
                Quagga.stop();
            }
        };
    }, [scanning, onScan]);

    return (
        <div>
            <button
                style={{     //css調整
                    width: "50%",
                    margin: "0 auto",
                    display: "block",
                    border: "1px solid black",
                }}
                onClick={() => setScanning(true)}
            >
                バーコードスキャン
            </button>
            {scanning && (
                <div
                    ref={videoRef}
                    style={{ width: "80%", height: "50%", margin: "0 auto" }}     //css調整
                />
            )}
        </div>
    );
};

export default BarcodeScanner;

ZXing

import { BrowserMultiFormatReader } from "@zxing/library";
import { useEffect, useRef, useState } from "react";

const BarcodeScanner = ({ onScan }: { onScan: (code: string) => void }) => {
    const [scanning, setScanning] = useState(false);
    const videoRef = useRef<HTMLVideoElement>(null);

    useEffect(() => {
        if (scanning) {
            const codeReader = new BrowserMultiFormatReader();
            codeReader.decodeFromVideoDevice(
                null,
                videoRef.current,
                (result, err) => {
                    if (result) {
                        onScan(result.getText());
                        setScanning(false);
                        codeReader.reset();
                    }
                }
            );
        }
    }, [scanning, onScan]);

    return (
        <div>
            {!scanning ? (
                <button
                    style={{      //css調整
                        width: "50%",
                        height: "100px",
                        margin: "0 auto",
                        display: "block",
                        border: "1px solid black",
                        backgroundColor: "white",
                        font: "bold 18px sans-serif",
                    }}
                    onClick={() => setScanning(true)}
                >
                    バーコードで検索<br></br>(カメラを起動)
                </button>
            ) : (
                "カメラ起動"
            )}
            {scanning && (
                <video
                    ref={videoRef}
                    style={{   //css調整
                        width: "90%",
                        height: "60%",
                        margin: "0 auto",
                    }}
                />
            )}
        </div>
    );
};

export default BarcodeScanner;

まとめ

最終的に、「商品の同一性」判定が目的であり、将来的にバーコードが2DのQRコードに変わっていく可能性も考え、ZXingを利用することにした。
ここで読み取ったコードをもとに、yahoo shoppingAPIを叩いて該当商品があれば商品名を取得する。もし、登録済み商品のデータがあれば、その情報を表示する仕様にした。
次回は、本アプリで検索機能を何度か実装したので、それに関する備忘録を残す予定。


0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?