きっかけ
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コードの読み込みはカメラの設定に苦戦したがしたいことができて満足しました
参考