LoginSignup
0
0

【備忘録】Next.jsでQRコード生成と読み込み

Posted at

きっかけ

QRコードを使用してデータを取得したい

したこと

2つのライブラリを使用

  • qrcode.react
    生成するためのライブラリ
    npm install qrcode.react
    
  • jsqr
    読み込むためのライブラリ
    npm install jsqr --save
    

QRコード生成

生成の方は簡単でqrcode.reactをimportしてQRコードにいれたい値とサイズを指定するだけです

page.tsx
import { QRCodeCanvas } from "qrcode.react"

export default function Page(){
    return(
        <QRCodeCanvas value="適当な値" size="お好みで">
    )
}

ただしcanvasで生成されるので注意が必要です。

QRコード読み取り

まずカメラの取得し、その情報からcanvasに変換をし、そのcanvasからQRコードか判別します。

qr_camera.tsx
import {useState, useEffect, useRef} from 'react'
import jsQR from 'jsqr'

export default function Qr_Camera(){
    const videoRef = useRef<HTMLVideoElement>(null)
    const canvasRef = useRef<HTMLCanvasElement>(null)

    const [contentWidth, setContentWidth] = useState<number>(カメラの横幅)
    const [contentHeight, setContentHeight] = useState<number>(カメラの縦幅)
    useEffect(() => {
        const config = { audio:false, video: { facingMode: "environment" }}
        const ctx = canvasRef.current?.getContext('2d')
        const canvasUpdate = () => {
            if (ctx && videoRef.current && canvasRef.current) {
                canvasRef.current.width = contentWidth
                canvasRef.current.height = contentHeight
                ctx.drawImage(videoRef.current, 0, 0, contentWidth, contentHeight)
                requestAnimationFrame(canvasUpdate)
            }
        }
        const checkImage = async() => {
            if(ctx && videoRef.current){
                ctx?.drawImage(videoRef.current, 0, 0, contentWidth, contentHeight)
                const imageData = ctx.getImageData(0, 0, contentWidth, contentHeight)
                if (imageData) {
                    const code = jsQR(imageData.data, contentWidth, contentHeight)
                    if (code) {
                        // QRコードの情報が表示されます
                        console.log(code.data)
                    }
                }
                setTimeout(()=>{ checkImage() }, 200);
            }
        }
    
        navigator.mediaDevices.getUserMedia(config)
        .then(stream => {
            if (videoRef.current) {
                videoRef.current.srcObject = stream
                videoRef.current.onloadedmetadata = () => {
                    if (videoRef.current){
                        videoRef.current.play()
                        setContentWidth(videoRef.current.clientWidth)
                        setContentHeight(videoRef.current.clientHeight)
                        canvasUpdate()
                        checkImage()
                    }
                }
            }
        })
        .catch(err => {
            console.log(err)
        })
    },[contentWidth, contentHeight])

    return(
        <>
            // 今回はvideoをカメラとして使用していますがcanvasでも可です
            <video ref={videoRef} autoPlay playsInline width={contentWidth} height={contentHeight}></video>
            // tailwindCSSを使用していますが単純なcssでhiddenにしても大丈夫です
            <canvas ref={canvasRef} className='hidden'></canvas>
        </>
    )
}

まとめ

QRコードの生成はqrcode.reactで簡単に実装でき、QRコードの読み込みはカメラの設定に苦戦したがしたいことができて満足しました

参考

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