背景少し前にブラウザカメラの取得とスキャンコード認識の機能を作りました。その際の知識ポイントと具体的なコード実装を整理して記事の内容にまとめました。 この記事では主に、 成果を達成するこの例では、ホームページと QR コードスキャンページの 2 つのメインページがあります。具体的な実装効果は、次の図に示されています。
オンライン体験: https://dragonir.github.io/h5-scan-qrcode ヒント: カメラデバイスを備えたブラウザで縦向きモードでアクセスする必要があります。携帯電話の横画面と縦画面の検出に関するその他のヒントについては、私の別の記事「Gokudō ゲームにおけるフロントエンドの知識」をご覧ください。 技術紹介WebRTC API WebRTC (Web Real-Time Communications) は、ネットワーク アプリケーションまたはサイトが、仲介者の助けを借りずにブラウザー間で 3 つの主なインターフェース:
WebRTC アダプター
コア API Web ページは、カメラを呼び出すために これは navigator.mediaDevices.getUserMedia(制約) .then(関数(ストリーム) { // このストリームを使用する }) .catch(関数(エラー) { // エラーを処理する }) QRコード解析ライブラリ const code = jsQR(imageData, 幅, 高さ, オプション); if (コード) { console.log('QRコードが見つかりました!', code); } コードの実装プロセスコードスキャンのプロセス全体を下図に示します。ページが初期化され、まずブラウザが 以下の内容はプロセスを分割し、それぞれ対応する機能を実装します。 ページ構造まず、主に
<テンプレート> <div class="スキャナー" ref="スキャナー"> <!-- プロンプト ボックス: 互換性のないブラウザでプロンプトを表示するために使用されます--> <div class="banner" v-if="showBanner"> <i class="close_icon" @click="() => showBanner = false"></i> <p class="text">現在のブラウザでコードをスキャンできない場合は、別のブラウザに切り替えてお試しください</p> </div> <!-- スキャンコードボックス: スキャンコードアニメーションを表示します--> <div class="カバー"> <p class="line"></p> <span class="square 左上"></span> <span class="square 右上"></span> <span class="square 右下"></span> <span class="square 左下"></span> <p class="tips">QR コードをボックスに入れると自動的にスキャンされます</p> </div> <!-- ビデオ ストリームの表示 --> <ビデオ v-show="showPlay" クラス="ソース" ref="ビデオ" :width="ビデオWH.width" :height="ビデオWH.height" コントロール </ビデオ> <canvas v-show="!showPlay" ref="canvas" /> <button v-show="showPlay" @click="run">開始</button> </div> </テンプレート> 方法: 描画
// 線を描く drawLine (begin, end) { パスの開始位置を指定します。 this.canvas.moveTo(begin.x, begin.y); this.canvas.lineTo(終了x、終了y); キャンバスの線幅を設定します。 this.canvas.strokeStyle = this.lineColor; キャンバスのストローク }, // 描画ボックス (場所) { if (this.drawOnfound) { this.drawLine(location.topLeftCorner、location.topRightCorner); this.drawLine(location.topRightCorner, location.bottomRightCorner); this.drawLine(location.bottomRightCorner, location.bottomLeftCorner); this.drawLine(location.bottomLeftCorner、location.topLeftCorner); } }, 方法: 初期化
// 初期化セットアップ () { // ブラウザが MediaDevices.getUserMedia() に搭載されたメソッドをサポートしているかどうかを判定します if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) { this.previousCode = null; this.parity = 0; this.active = true; this.canvas = this.$refs.canvas.getContext("2d"); // カメラモードを取得します。デフォルト設定は背面カメラです。const facingMode = this.useBackCamera ? { exact: 'environment' } : 'user'; // カメラビデオ処理 const handleSuccess = stream => { if (this.$refs.video.srcObject !== 未定義) { this.$refs.video.srcObject = ストリーム; } そうでない場合 (window.videoEl.mozSrcObject !== 未定義) { this.$refs.video.mozSrcObject = ストリーム; } それ以外の場合 (window.URL.createObjectURL) { this.$refs.video.src = window.URL.createObjectURL(ストリーム); } それ以外の場合 (window.webkitURL) { this.$refs.video.src = window.webkitURL.createObjectURL(ストリーム); } それ以外 { this.$refs.video.src = ストリーム; } // ユーザーにプログレス バーをドラッグさせたくない場合は、playsinline 属性を直接使用できます。webkit-playsinline attribute this.$refs.video.playsInline = true; const playPromise = this.$refs.video.play(); 再生Promise.catch(() => (this.showPlay = true)); // ビデオの再生が開始されたら、識別のためにコードを定期的にスキャンします。playPromise.then(this.run); }; // ビデオストリームをキャプチャするnavigator.mediaDevices .getUserMedia({ ビデオ: { 向きモード } }) .then(ハンドル成功) .catch(() => { ナビゲーター.メディアデバイス .getUserMedia({ビデオ: true }) .then(ハンドル成功) .catch(エラー => { this.$emit("error-captured", error); }); }); } }, 方法: 定期スキャン 走る () { アクティブの場合 // ブラウザは、次の再描画の前にループ内でスキャン メソッド requestAnimationFrame(this.tick) を呼び出します。 } }, メソッド: 成功コールバック // QRコード認識成功イベント処理が見つかりました(コード){ if (this.previousCode !== コード) { this.previousCode = コード; } それ以外の場合 (this.previousCode === code) { this.parity += 1; } (このパリティ>2)の場合{ this.active = this.stopOnScanned ? false の場合、 true; this.parity = 0; this.$emit("code-scanned", コード); } }, 方法: 停止 // 終止符 fullStop () { (this.$refs.video && this.$refs.video.srcObject) の場合 { // ビデオ ストリーム シーケンス トラックを停止します。this.$refs.video.srcObject.getTracks().forEach(t => t.stop()); } } 方法: スキャン
// 定期的なコードスキャンと認識 tick () { // ビデオは準備段階にあり、十分なデータが読み込まれています if (this.$refs.video && this.$refs.video.readyState === this.$refs.video.HAVE_ENOUGH_DATA) { // キャンバスにビデオの描画を開始します。this.$refs.canvas.height = this.videoWH.height; this.$refs.canvas.width = this.videoWH.width; this.canvas.drawImage(this.$refs.video, 0, 0, this.$refs.canvas.width, this.$refs.canvas.height); // getImageData() はキャンバス上の指定された四角形のピクセル データをコピーします。const imageData = this.canvas.getImageData(0, 0, this.$refs.canvas.width, this.$refs.canvas.height); code = false とします。 試す { // QR コードを認識する code = jsQR(imageData.data, imageData.width, imageData.height); } キャッチ (e) { コンソールエラー(e); } // QRコードが認識された場合、長方形のボックスを描画します if (code) { this.drawBox(コードの場所); // 成功したイベント処理を識別します this.found(code.data); } } これを実行してください。 }, 親コンポーネント
ページ構造 <テンプレート> <div class="scan"> <!-- ページナビゲーションバー--> <div class="nav"> <a class="close" @click="() => $router.go(-1)"></a> <p class="title">QR コードをスキャン</p> </div> <div class="スクロールコンテナ"> <!-- スキャンコードサブコンポーネント--> <スキャナー v-on:code-scanned="コードスキャン済み" v-on:error-captured="エラーキャプチャ済み" :スキャン時に停止="true" :draw-on-found="true" :responsive="false" /> </div> </div> </テンプレート> 親コンポーネントメソッド Scaner を '../components/Scaner' からインポートします。 エクスポートデフォルト{ 名前: 'スキャン'、 コンポーネント: スキャナー }, データ () { 戻る { エラーメッセージ: "", スキャン済み: "" } }, メソッド: { コードスキャン済み(コード) { this.scanned = コード; タイムアウトを設定する(() => { alert(`コードをスキャンして解析に成功しました: $[code]`); }, 200) }, errorCaptured(エラー) { スイッチ (エラー.name) { ケース「NotAllowedError」: this.errorMessage = "カメラの許可が拒否されました。"; 壊す; 「NotFoundError」の場合: this.errorMessage = "接続されたカメラがありません。"; 壊す; ケース「NotSupportedError」: this.errorMessage = 「このページは安全でないコンテキストで提供されているようです。」; 壊す; ケース「NotReadableError」: this.errorMessage = 「カメラにアクセスできませんでした。すでに使用されていますか?」; 壊す; ケース「OverconstrainedError」: this.errorMessage = "制約はインストールされているカメラと一致しません。"; 壊す; デフォルト: this.errorMessage = "不明なエラー: " + error.message; } コンソールエラー(このエラーメッセージ); alert('カメラの呼び出しに失敗しました'); } }, マウントされた(){ var str = navigator.userAgent.toLowerCase(); var ver = str.match(/cpu iphone os (.*?) like mac os/); // テストの結果、iOS 10.3.3未満のシステムではカメラを正常に呼び出すことができません if (ver && ver[1].replace(/_/g,".") < '10.3.3') { alert('カメラの呼び出しに失敗しました'); } } 完全なコード
要約するアプリケーション拡張機能ブラウザ経由でカメラを呼び出してスキャン・識別することで、以下のような機能が実現できると思います。 ブラウザ側のコードをスキャンすることで、他にどんな
互換性
参考文献 [1] WebRTCで静止画を撮影する [2] mediaDevices APIを使用してJavaScriptでカメラを選択する [3] JavaScriptを使用してデバイスの前面カメラと背面カメラにアクセスする方法 著者: dragonir 記事URL: https://www.cnblogs.com/dragonir/p/15405141.html Vue のブラウザ側コードスキャン機能の実装に関するこの記事はこれで終わりです。より関連性の高い vue ブラウザコードスキャンのコンテンツについては、123WORDPRESS.COM の過去の記事を検索するか、以下の関連記事を引き続き閲覧してください。皆様、今後とも 123WORDPRESS.COM を応援してください。 以下もご興味があるかもしれません:
|
<<: docker に openjdk をインストールして jar パッケージを実行する方法
>>: HTML テーブル マークアップ チュートリアル (29): セルのライト境界線の色属性 BORDERCOLORLIGHT
1. CSS 方法論とは何ですか? CSS methodologiesデザイン パターンまたは CS...
問題の説明フロントエンドリモート検索やファジークエリと呼ばれる種類のクエリがあります。 Ele.me...
通常、人事担当者と会うことはめったにありませんが、一度会うと、それが生死を分けることもあります。 H...
1 はじめにApache Storm は、Hadoop と同様に、大量のデータを処理するために使用で...
序文Linux 上で jar パッケージを実行する方法は誰もが知っています。なぜ別々に話したいのでし...
1. 遷移属性の理解1. transition 属性は、次の 4 つの遷移プロパティを設定するために...
他の人のために解決した問題を記録します。問題の説明MySQLのバージョンは5.7、オペレーティングシ...
<meta name="viewport" content="w...
1: dockerにmongodbをインストールするステップ1: dockerにmongodbをイン...
目次ステップ1: インストールステップ2: 引用ステップ3: 使用Webプロジェクトでは、データを読...
データベースでcreate tableステートメントを実行する テーブル `sys_acl` を作成...
HTML CSS および JavaScript を使用して、プラス、マイナス、ゼロの 3 つのボタン...
High Performance MySQL バージョン 3 (セクション 4.1.7) を見ると、...
目次環境: 1. Dockerはリモート接続アクセスを可能にするidea dockerプラグインをイ...
目次導入インデックスの原則1. データページ2. ページディレクトリ3. インデックス原則分析要約す...