QRコードリーダー

画像ファイルまたはPC・スマートフォンのカメラ映像を解析し,QRコードから読み取った文字列を表示・コピーします.HTTP/HTTPS URLは手動で開けますが,Wi-Fi設定の展開,短縮URLの展開,ドメインの安全判定は行いません.

読み込み中...

このツールが向いている用途

操作欄に戻る ↑

画像ファイルやカメラ映像からQRコードを読み取り,格納された文字列を表示・コピーできます.画像はこのブラウザ内で処理します.

まず試せること

まず鮮明なQR画像を選んでください.読めない場合は,角の位置検出マーカーと周囲の余白を含めた画像を試してください.

利用条件

読み取ったURLの安全性判定は行わないため開く前に宛先をご確認ください。HTTP(S)以外のスキームは文字列表示のみとなり、カメラ利用時は対応環境と権限が必要です。

ZeroToolsのブラウザ内処理とプライバシー

ZeroToolsは,入力内容を端末内で処理するツールを中心に提供しています.各ツールの対応範囲と制限を確認して利用してください.

データの取り扱い・プライバシー方針
第1章

画像ファイルによるQRコード解析プロセス

画像ファイルを用いたQRコードの読み取りは,Reactコンポーネント内の状態管理と標準Web APIを組み合わせたローカル処理によって実現されています.利用者がUI上の「画像ファイル」タブ(activeTab状態が"upload")を選択し,ファイル選択ダイアログまたはドラッグアンドドロップ領域を通じてファイルを指定すると,handleImageUpload関数が発火します.

この処理では,input要素(type="file", accept="image/*")から取得されたFileオブジェクトをFileReader APIのreadAsDataURLメソッドを用いてBase64形式のData URL文字列へと変換します.Data URLへの変換が完了すると,onloadイベント内で状態変数uploadedImageに値が保持され,プレビュー画像としての表示(img要素へのsrc割り当て)が行われると同時に,解析用のdecodeImage関数が呼び出されます.

decodeImage関数では,新しいImageオブジェクトを生成し,Data URLをsrcプロパティに代入して画像の読み込みを待機します.読み込み完了(img.onload)後,UI上には表示されない非表示設定のcanvas要素(imageCanvasRefで参照されるDOM)を画像解析のためのバッファとして利用します.

この際,canvasのwidthおよびheightプロパティには,CSS等による拡縮の影響を受けていないImageオブジェクト固有のnaturalWidthとnaturalHeightがそのまま代入されます.これにより,画像が持つ本来のピクセル解像度を維持した描画領域が確保されます.

確保された領域に対し,CanvasRenderingContext2DのdrawImageメソッドを使用して画像全体を座標(0, 0)を起点として描画します.続いて,getImageDataメソッドを(0, 0, canvas.width, canvas.height)の引数で呼び出すことで,Canvas上の全ピクセルデータをRGBAの一次元配列(Uint8ClampedArray)として内包するImageDataオブジェクトを抽出します.

この配列データこそが後続のデコード処理の入力値となります.画像のアップロード処理からCanvasへの描画,ピクセルデータの抽出に至るまで,画像解析の処理はクライアントのブラウザメモリ内で実行され,このコンポーネントには画像を解析用サーバーへ送る処理はありません.

サイト配信や他のページ通信とは区別して考える必要があります.エラーが発生した場合(例えば,QRコードが含まれていない画像がアップロードされた場合)は,setError関数を通じて「画像からQRコードを検出できませんでした.画像が鮮明であるか,または角のマーカーが含まれているか確認してください.

」という固定のエラーメッセージが状態としてセットされ,画面上に警告アイコン(AlertTriangle)とともに表示されます.実務上の使い方としては,スクリーンショットやデバイス内に保存されている画像から直接情報を抽出したい場面で,ネットワーク通信を伴うことなくローカル環境下で迅速な解析を実行する用途に適しています.

第2章

カメラ映像を利用したリアルタイムスキャン機能

カメラを利用したスキャン処理は,activeTab状態が"camera"に切り替わったタイミング,または利用者が「スキャンを開始」ボタンを押下した際に実行されるstartCamera関数によって駆動します.本機能の根幹は,navigator.mediaDevices.getUserMediaメソッドを用いた映像ストリームの取得処理にあります.

このメソッドを呼び出す際,引数として指定される制約オブジェクト(constraints)には,videoプロパティが含まれており,背面・前面カメラの指定(facingMode: cameraFacing)に加えて,解像度の理想値として幅(width: { ideal: 1280 })および高さ(height: { ideal: 720 })が設定されています.

ストリームの取得に成功すると,戻り値であるMediaStreamオブジェクトがstreamRefとして保持され,非表示のvideo要素(playsInlineおよびmuted属性が付与されたvideoRef)のsrcObjectに代入されます.

video要素のメタデータ読み込みが完了する(onloadedmetadataイベント発火)と,video.play()が実行され,状態変数cameraActiveがtrueへと更新されます.この瞬間から,requestAnimationFrameを用いた再帰的なフレーム解析ループ(tick関数)が起動します.

tick関数内では,video.readyStateがHAVE_ENOUGH_DATA(データが十分に存在する状態)であることを条件として,毎フレームごとに映像をバッファ用のcanvas要素(videoCanvasRef)へ転写します.canvasのサイズはvideo.videoWidthおよびvideo.videoHeightに同期され,ctx.drawImageによって映像の現在フレームが描画された後,ctx.getImageDataを用いてピクセルデータ(ImageData)が抽出されます.

抽出されたデータは直ちにデコードエンジンへと渡され,QRコードの検出が試みられます.

カメラ映像の解析処理において特筆すべき点は,QRコードの検出に成功した瞬間の挙動です.有効なデータが取得された場合,ただちにstopCamera関数が呼び出されます.この関数内では,cancelAnimationFrameによる再帰ループの停止,MediaStreamに属するすべてのtrackに対するstopメソッドの実行,およびvideo要素のsrcObjectの破棄(null代入)が順番に行われます.

これにより,解析完了後はカメラデバイスへのアクセスが即座に解放され,端末のリソース消費(バッテリーやCPU)が最小限に抑止されます.実務上の使い方としては,対象となるQRコードにデバイスを向けるだけで連続的なフレーム解析が行われるため,静止画を撮影・保存する手間を省き,リアルタイムかつシームレスに文字列データを取り出す用途に適しています.

また,コンポーネントのアンマウント時やタブ切り替え時にもuseEffectのクリーンアップ関数によって確実にストリームが停止される設計となっており,バックグラウンドでの意図しないカメラ稼働を防ぎます.

第3章

jsQRライブラリによるピクセルデータのデコード処理

画像ファイルおよびカメラ映像から抽出されたピクセルデータ(ImageData)の解析には,純粋なJavaScript実装のQRコード解析ライブラリであるjsQRが採用されています.抽出されたImageDataに含まれる一次元RGBA配列(imageData.data)は,画像の幅(imageData.width)および高さ(imageData.height)とともに,jsQR関数の引数として直接渡されます.

このデコード処理において,本ツールは特定のオプションオブジェクト { inversionAttempts: "dontInvert" } を明示的に指定しています.この制約パラメータは,jsQRが暗い背景に明るい色で描画されたQRコード(いわゆる白黒反転されたQRコード)の読み取りを試行する処理をスキップさせる役割を持ちます.

白黒反転の探索を省略することで,標準的な白色背景・黒色モジュールのQRコードに対する解析処理のオーバーヘッドが削減され,メインスレッド上での同期的実行におけるブロック時間を短縮する効果があります.

jsQRは入力されたピクセルデータ内から,QRコード特有の位置検出パターン(ファインダパターン,通常は3つの角に配置される二重の正方形)を探索します.パターンが検出されると,モジュールサイズや画像の傾きを算出し,誤り訂正レベルに応じた復元処理を経て,エンコードされている生の文字列データを抽出します.

デコードに成功した場合,jsQR関数は文字列データ(code.data)および検出位置の座標情報(code.location)をプロパティに持つオブジェクトを返却します.本ツールでは,この座標情報を活用し,カメラ映像のキャンバス上に視覚的なフィードバックを描画する処理が実装されています.

具体的には,code.locationが保持する4つの角の座標(topLeftCorner, topRightCorner, bottomRightCorner, bottomLeftCornerのxおよびyプロパティ)をmoveToおよびlineToメソッドで連結し,lineWidthを4,strokeStyleを緑色(#10b981)に設定したパスを描画(stroke)することで,QRコードの境界線を強調表示します.

結果として返却される文字列データは,元のエンコード形式に依存しますが,本ツールではjsQRがデコードした生の文字列をそのままの状態で取得します.解析処理において,文字コードの自動判定の補正や,欠損が激しいQRコードの強制的な復元などは行われません.実務上の使い方としては,jsQRによる解析結果がそのまま次の出力フェーズへ渡されるため,利用者はjsQRが復号した文字列を追加分類なしで確認できます.

画像状態や符号化内容によっては復号できない場合があり,元データの完全復元を保証するものではありません.ピクセル配列の走査から文字列の抽出に至るまでの演算処理は,すべて利用者のブラウザ上で実行され,このコンポーネントには外部のデコード用APIや画像認識サーバーへ送る処理は組み込まれていません.

サイト配信等の通信とは別です.

第4章

読み取り結果の表示・コピー・リンク判定機能

jsQRによって抽出された文字列データは,状態変数resultに格納され,「スキャン結果」領域にプレビュー表示されます.表示領域は等幅フォント(font-mono)が適用され,改行コードを保持する形式(whitespace-pre-wrap)かつ長い文字列の折り返し(break-all)が有効化されたレイアウトで構成されています.

また,利用者自身が文字列を選択しやすいよう,CSSのselect-allプロパティが付与されており,最大高さ(max-h-[160px])を超過するデータについては垂直スクロール(overflow-y-auto)によって全体を閲覧できる構造となっています.取得された文字列はそのままの状態で表示され,Wi-Fi設定文字列(WIFI:T:WPA;S:SSID;P:PASSWORD;;など)の自動展開や,短縮URLの展開処理など,内容に応じた自動的な分類や変換処理は実行されません.

表示された結果に対するアクションとして,本ツールは「クリップボードへのコピー」と「URLとしての遷移」の2つの機能を提供しています.コピー機能(copyResult関数)は,navigator.clipboard.writeTextメソッドを呼び出すことで,抽出された生文字列をOSのクリップボードへ直接書き込みます.

書き込み処理が成功すると,状態変数copiedがtrueに切り替わり,UI上のボタンアイコンがチェックマークへ変化すると同時に「コピーしました!」というテキストが表示されます.この状態はsetTimeoutによって2秒間(2000ミリ秒)維持された後,元の表示へと復帰します.

リンク判定機能は,取得した文字列が有効なWebサイトのURLであるか否かを厳密な条件で検証します.isUrl関数内において,文字列をnew URL()コンストラクタへ渡し,パースに成功した場合に限りプロトコル(scheme)の評価を行います.ここで,url.protocolが "http:" または "https:" のいずれかに合致する場合のみ,URLとして有効である(true)と判定されます.

この制約により,javascript:(スクリプト実行)やdata:(データ埋め込み),file:(ローカルファイル参照)などのそれらのプロトコルはリンクとして扱われません.ただし,http/httpsのURLであっても遷移先の安全性を確認したことにはなりません.

有効なHTTP/HTTPSリンクであると判定された場合のみ,「リンクを開く」ボタン(ExternalLinkアイコン付き)がUI上に表示され,ボタン押下時にwindow.open(result, "_blank", "noopener,noreferrer")が実行されることで,新規タブにて対象ページへと遷移します.

実務上の使い方としては,文字列のコピーを基本としつつ,一般的なWebページへの遷移のみをシームレスに行う手動操作主体のインターフェースとして機能します.

第5章

カメラ利用時の権限と端末環境への依存

カメラを利用したスキャン機能は,OSやブラウザが提供するメディアデバイスアクセス権限と深く結びついており,実行環境に対する明確な依存性と制約を持ちます.navigator.mediaDevices.getUserMediaメソッドの呼び出しは,ブラウザのセキュリティポリシーにより,通信プロトコルがHTTPSであること,もしくはローカル環境(localhostまたは127.0.0.1)での実行であることが要求されます.

この条件を満たさない環境(例えば,暗号化されていないHTTP接続)では,メソッド自体が定義されないか,無条件でエラーとなります.さらに,条件を満たしている場合であっても,利用者に対してカメラ利用の許可を求めるプロンプトがブラウザ側から提示され,明示的な承諾が得られない限り処理は進行しません.

アクセスが拒否された場合やハードウェア的な不具合が発生した場合,catchブロックへ例外(err)が渡され,setError関数を通じて「カメラの起動に失敗しました.カメラへのアクセス許可を確認するか,画像アップロード機能をご利用ください.」という固定メッセージが画面上に表示されます.

カメラの切り替え機能については,状態変数cameraFacingを用いて "user"(前面カメラ)と "environment"(背面カメラ)をトグルするswitchCamera関数が実装されています.切り替えボタンが押下されると,現在のカメラストリームを停止(stopCamera)した上で,新たなfacingMode制約を付与して再度ストリームを取得し直すサイクルが実行されます.

ただし,ここで指定されるfacingModeはブラウザおよびOSに対する「希望値(ideal)」としての要求であり,ハードウェア構成やOSの仕様によっては,必ずしも指定した通りのカメラが起動するとは限らないというプラットフォーム依存の性質を持ちます.例えば,背面カメラが複数存在する最新のスマートフォンでは,どのレンズが選択されるかはブラウザの実装に委ねられます.

実務上の使い方としては,端末の環境差異による不確実性を考慮し,カメラの起動に失敗した場合の代替手段として,常に第1章で述べた画像アップロード機能への導線を確保することが重要です.また,処理中はUI上に「一時停止」や「カメラ切り替え」といった制御ボタンを配置し,利用者が任意のタイミングでハードウェアの占有を解除できる設計となっています.

第6章

読み取り失敗条件と安全確認における留意点

QRコードの読み取りプロセスにおいて,結果が正しく得られない場合の条件や,UIの視覚的表現と実際の内部処理の差異,そして通信やセキュリティ上の仕様について正しく把握しておく必要があります.本ツールのカメラ映像解析時,画面上には180px四方または240px四方(画面サイズに依存)の枠線や,上下にバウンドするレーザー風のグラデーション要素(CSSのanimate-bounceによるアニメーション)が表示されます.

これらはすべてHTMLおよびCSSによって装飾された視覚的な目安(ポインターイベントを無効化したオーバーレイ)に過ぎません.実際の内部処理においては,この枠内にQRコードが収まっているかどうかを計算してトリミングを行っているわけではなく,video要素の全画面解像度(canvasに転写された全体積)を対象としてjsQRによる走査が実行されています.

読み取りに失敗する条件としては,画像ファイル・カメラ映像の両方に共通して,元のピクセルデータに十分な情報が含まれていない状況が挙げられます.例えば,画像の解像度が極端に低い場合,カメラの焦点が合っておらず映像がぼやけている場合,照明が暗くコントラストが不足している場合,QRコードが極端に斜めから撮影され歪みが大きい場合,または位置検出パターンの欠損や汚れが存在する場合などです.

本ツールには,暗部の自動補正,歪みの補正処理,連続フレームからの超解像度処理などは実装されておらず,jsQRがフレーム内でファインダパターンを検出できなかった場合は結果としてnullが返却され,エラーメッセージの表示または次のフレーム解析への移行が行われます.

安全確認に関する留意点として,第4章で述べたURLのscheme判定(http/https)は,あくまでリンクとしてブラウザで開くための最低限の要件定義であり,対象となるドメインが悪意のないものであるか(フィッシングサイトでないか),あるいはマルウェアが含まれていないかを検証するものではありません.

ウイルス検査やドメイン判定処理は実装されておらず,遷移先の信頼性に関する最終的な判断は利用者に委ねられます.また,「外部サーバーへの通信は発生しません」という説明は,本ツールがQRコードの画像データや抽出した文字列を解析・収集する目的で自発的にバックエンドへ送信する処理(fetchやXMLHttpRequestなど)を一切実装していないという事実に基づいています.

しかし,カメラによる連続解析プロセス自体は,requestAnimationFrameによる高頻度なループ処理としてメインスレッドで実行されるため,端末のCPUやバッテリーリソースを継続的に消費するという物理的な制約を伴います.実務上の使い方としては,これらのローカル処理の特性と限界を把握した上で,長時間カメラを稼働させたまま放置せず,必要な読み取りが完了した後は速やかにストリームを停止させる運用が推奨されます.

よくある質問(FAQ)

A.
はい.画像ファイルを選択するかドラッグ&ドロップすると,ブラウザが画像をCanvasへ描画し,jsQRで解析します.PNG,JPEG,WebPなどブラウザが読み込める一般的な画像を利用できます.
A.
ブラウザのカメラ利用許可が必要です.通常はHTTPSまたはlocalhostで提供されたページで利用でき,端末やブラウザによって背面カメラの指定どおりにならない場合があります.
A.
いいえ.読み取った文字列がHTTPまたはHTTPSで始まる場合にリンクを表示するだけで,フィッシング,マルウェア,短縮URLの遷移先などは検査しません.開く前にドメイン名を確認してください.
A.
QR解析はブラウザ内のjsQRで行います.カメラ利用時は映像フレームを連続解析するため,端末のCPUやバッテリーを消費します.読み取り後は不要になったカメラを停止してください.