VueはPCカメラを呼び出して写真機能を実現します

VueはPCカメラを呼び出して写真機能を実現します

この記事の例では、VueがPCカメラを呼び出して写真機能を実現する具体的なコードを参考までに共有しています。具体的な内容は次のとおりです。

プロジェクト要件:アバターをローカルにアップロードすることも、写真を撮ってアップロードすることもできます。

コンポーネント:

1. カメラコンポーネント:カメラの開閉、描画、画像の表示、アップロードを実現する
2. CameraDialogコンポーネント: ElementUIダイアログコンポーネントを使用してカメラUI効果を表示する
3. ポートレートをアップロードする機能を実現するために、CameraDialogコンポーネントを外部から呼び出します。
4. ローカルアップロードではネイティブ入力またはElementUIアップロードコンポーネントを使用できます

操作ロジック:

1. 追加時にアバター画像をbase64に変換して呼び出しインターフェースに送信し、フロントエンド表示用のURLアドレスを返します。
2. 置換する場合は、まず削除操作を行い、その後追加操作を行います。
3. ローカルアップロードの原理は撮影アップロードと同じです

具体的な実施方法:

カメラコンポーネント

<テンプレート>
  <div class="カメラボックス">
    <ビデオ id="ビデオ" :width="ビデオ幅" :height="ビデオ高さ" v-show="!imgSrc"></ビデオ>
    <canvas id="canvas" :width="videoWidth" :height="videoHeight" v-show="imgSrc"></canvas>
    <p class="camera-p">{{!imgSrc?'ヒント: アバターを中央に配置して「写真」ボタンを押して確定してください':''}}</p>
    <el-button type="primary" @click="setImage" v-if="!imgSrc" class="camera-btn">写真を撮る</el-button>
    <el-button type="primary" v-if="imgSrc" @click="setFileUpload" class="camera-btn">アップロード</el-button>
  </div>
</テンプレート>

<スクリプト>
  「@/api/houseApi」から {setFileUpload、deleteFileUpload、addUserCard } をインポートします。

  エクスポートデフォルト{
    名前: 'カメラ'、
    小道具: {
      //【必須】CameraDialogポップアップウィンドウの表示ステータス show: {type: Boolean},
      //[オプション] 置換時に削除するには、ローカルアップロードのネイティブ入力を使用します。deleteData: {type: Object}
    },
    データ() {
      戻る {
        ビデオ幅: '401',
        ビデオの高さ: '340',
        thisCancas: null、
        thisContext: null、
        このビデオ: null、
        画像ソース: ``,
      }
    },
    マウント() {
      if (this.show) this.getCompetence()
    },
    メソッド: {
      /*
       *@著者 ブレイディ
       *@時刻 2019/9/5
       *@function 呼び出し権限************************************************/
      取得コンピテンス() {
        var _this = これ
        this.thisCancas = document.getElementById('canvas')
        this.thisContext = this.thisCancas.getContext('2d')
        this.thisVideo = document.getElementById('ビデオ')
        // 古いブラウザは mediaDevices をまったくサポートしていない可能性があるため、最初に空のオブジェクトを設定します if (navigator.mediaDevices === undefined) {
          ナビゲーター.mediaDevices = {}
        }
        // 一部のブラウザは部分的な mediaDevices を実装しており、既存のプロパティを上書きしてしまうため、getUserMedia を使用してオブジェクトを割り当てることはできません。
        // ここで、getUserMedia プロパティが欠落している場合は追加します。
        navigator.mediaDevices.getUserMedia が未定義の場合 {
          navigator.mediaDevices.getUserMedia = 関数 (制約) {
            // まず既存の getUserMedia を取得します (存在する場合)
            var getUserMedia = navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.getUserMedia
            // 一部のブラウザではサポートされていないため、エラーメッセージが返されます // インターフェイスの一貫性を保つ if (!getUserMedia) {
              return Promise.reject(new Error('getUserMedia はこのブラウザでは実装されていません'))
            }
            // それ以外の場合は、古い navigator.getUserMedia の呼び出しを Promise でラップします。
            新しいPromise(function(resolve,reject))を返す{
              getUserMedia.call(ナビゲーター、制約、解決、拒否)
            })
          }
        }
        var 制約 = {
          オーディオ: 偽、
          ビデオ: {幅: this.videoWidth、高さ: this.videoHeight、変換: 'scaleX(-1)'}
        }
        navigator.mediaDevices.getUserMedia(制約).then(関数(ストリーム) {
          // 古いブラウザにはsrcObjectがない可能性があります
          _this.thisVideo に 'srcObject' がある場合、
            _this.thisVideo.srcObject = ストリーム
          } それ以外 {
            // 新しいブラウザでは非推奨となっているため、使用しないでください。
            _this.thisVideo.src = window.URL.createObjectURL(ストリーム)
          }
          _this.thisVideo.onloadedmetadata = 関数 (e) {
            _this.thisVideo.play()
          }
        }).catch(エラー => {
          コンソール.log(エラー)
        })
      },
      /*
       *@著者 ブレイディ
       *@時刻 2019/9/5
       *@function 画像を描く************************************************/
      setImage() {
        var _this = これ
        // クリック、キャンバス drawing_this.thisContext.drawImage(_this.thisVideo, 0, 0, _this.videoWidth, _this.videoHeight)
        // 画像の base64 リンクを取得します var image = this.thisCancas.toDataURL('image/png')
        _this.imgSrc = 画像
        // コンソールログ(_this.imgSrc)
        // this.$emit('refreshDataList', this.imgSrc)
      },
      /*
       *@著者 ブレイディ
       *@時刻 2019/9/5
       *@function base64 変換ファイル********************************************/
      dataURLtoFile(データURL、ファイル名) {
        var arr = dataurl.split(',')
        var mime = arr[0].match(/:(.*?);/)[1]
        var bstr = atob(arr[1])
        var n = bstr.長さ
        var u8arr = 新しい Uint8Array(n)
        (n--) {
          u8arr[n] = bstr.charCodeAt(n)
        }
        新しいファイルを返します([u8arr], ファイル名, {type: mime})
      },
      /*
       *@著者 ブレイディ
       *@時刻 2019/9/5
       *@function カメラを閉じる************************************************/
      ストップナビゲーター() {
        this.thisVideo.srcObject.getTracks()[0].stop()
      },
      //画像をアップロードする setFileUpload() {
        //ファイルを編集 - 顔写真をアップロード if (this.deleteData) {
          if (this.deleteData.imagePath) {
            ファイルアップロードを削除します({id: this.deleteData.id, ファイルパス: this.deleteData.imagePath})
              .then(res => {
                setFileUpload({画像: this.imgSrc})
                  .then(res => {
                    this.$emit('fileUpload', res.retData.filePath, res.retData.imagePath)
                    ユーザーカードを追加します({ユーザーID: this.deleteData.userid、カードタイプ: this.deleteData.cardType、ユーザー監査情報: res.retData.imagePath})
                      .then(res => {
                        this.$message({message: "アップロードに成功しました", type: "success"})
                      })
                      .catch(エラー => {
                        コンソール.log(エラー)
                      })
                  })
                  .catch(エラー => {
                    コンソール.log(エラー)
                  })
              })
              .catch(エラー => {
                コンソール.log(エラー)
              })
          } それ以外 {
            setFileUpload({画像: this.imgSrc})
              .then(res => {
                this.$emit('fileUpload', res.retData.filePath, res.retData.imagePath)
                ユーザーカードを追加します({ユーザーID: this.deleteData.userid、カードタイプ: this.deleteData.cardType、ユーザー監査情報: res.retData.imagePath})
                  .then(res => {
                    this.$message({message: "アップロードに成功しました", type: "success"})
                  })
                  .catch(エラー => {
                    コンソール.log(エラー)
                  })
              })
              .catch(エラー => {
                コンソール.log(エラー)
              })
          }
        } それ以外 {
          // 住民を追加 - 顔写真をアップロード setFileUpload({image: this.imgSrc})
            .then(res => {
              // コンソール.log(res)
              this.$message({message: "アップロードに成功しました", type: "success"})
              this.$emit('fileUpload', res.retData.filePath, res.retData.imagePath)
            })
            .catch(エラー => {
              コンソール.log(エラー)
            })
        }
      },
    },
    時計:
      表示(val) {
        if (値) {
          this.imgSrc = ``
          this.getCompetence()
        } それ以外 {
          this.stopNavigator()
        }
      },
    }
  }
</スクリプト>

<スタイル lang="less">
  .カメラボックス{
    マージン: 0 自動;
    テキスト配置: 中央;

    .カメラ-p {
      高さ: 17px;
      行の高さ: 17px;
      フォントサイズ: 12px;
      フォントファミリー: "PingFang SC";
      フォントの太さ: 400;
      色: rgba(154, 154, 154, 1);
      テキスト配置: 左;
    }

    .カメラボタン{
      上マージン: 20px;
    }

  }
</スタイル>

CameraDialog コンポーネント

<テンプレート>
  <div id="カメラダイアログ">
    <el-ダイアログ
            title="写真を撮る"
            :visible.sync="ダイアログを表示"
            トップ= "5vh"
            幅="481px"
            @close="ダイアログキャンセル"
            :クリック時に閉じるモーダル="false"
            :before-close="ダイアログキャンセル"
    >
      <カメラ:show="dialogVisible" :deleteData="deleteData" @fileUpload="fileUpload"></カメラ>
      <span slot="フッター" class="ダイアログフッター">
          <!-- <el-button @click="dialogCancle">キャンセル</el-button> -->
        <!-- <el-button type="primary">OK</el-button> -->
        </span>
    </el-ダイアログ>
  </div>
</テンプレート>

<スクリプト>
  「@/page/house/Camera.vue」からカメラをインポートします。

  エクスポートデフォルト{
    名前: 'CameraDialog',
    小道具: {
      dialogVisible: {type: ブール値},
      削除データ: {タイプ: オブジェクト}
    },
    コンポーネント:
      カメラ
    },
    データ() {
      戻る {
        ファイルパス: ``,
        イメージパス: ``,
      }
    },
    メソッド: {
      //ポップアップウィンドウを閉じる dialogCancle() {
        this.$emit('dialogCancle', false, this.filePath, this.imagePath);
      },
      //顔写真のアドレスを取得する fileUpload(filePath, imagePath) {
        this.filePath = ファイルパス
        this.imagePath = 画像パス
        this.dialogCancle()
      }
    }
  }
</スクリプト>

<スタイルスコープ>
</スタイル>

外部呼び出しコンポーネント

<テンプレート>
  <div>
    <div class="form-thumb">
     <img :src="ファイルパス" alt="">
      <i class="delete-btn" @click="deleteUploadFile" v-if="deleteData.imagePath">x</i>
    </div>
    <div class="アップロード-btn">
       <input type="file" name="userAuditInfo" id="userAuditInfo" @change="getUploadFile" ref="inputFile">
       <el-button type="defualt" size="small" @click="localUploadFile">ローカルアップロード</el-button>
       <el-button type="default" size="small" @click="dialogVisible=true">写真を撮る</el-button>
     </div>
    <!-- 写真を撮るためのポップアップウィンドウ-->
    <CameraDialog :dialogVisible="dialogVisible" @dialogCancle="dialogCancleCamera" :deleteData="deleteData" />
  </div> 
</テンプレート>

<スクリプト>
  「./CameraDialog.vue」からCameraDialogをインポートします。
  "@/api/houseApi.js" から { setFileUpload、deleteFileUpload、addUserCard } をインポートします。
  エクスポートデフォルト{
    データ() {
      戻る {
        filePath: require('@/assets/images/null.png'), //IDカードアバターdialogVisible: false,
        //顔写真関連フィールドを削除する操作 deleteData: {
          ユーザーID: this.$route.query.userId、
          id: ``,
          カードタイプ: 4,
          イメージパス: ``,
        }
   }
 },
 メソッド: {
      //クリックして顔写真をローカルにアップロードするのをシミュレートするlocalUploadFile() {
        this.$refs.inputFile.click()
      },
      //ローカルアップロード顔写真 getUploadFile() {
        入力 = document.getElementById('userAuditInfo')
        ファイルを input.files[0] とします
        this.getBase64(ファイル)
          .then(res => {
            if (this.deleteData.imagePath) {
              ファイルアップロードを削除します({id: this.deleteData.id, ファイルパス: this.deleteData.imagePath})
                .then(() => {
                  this.setFileUpload(res)
                })
            } それ以外 {
              this.setFileUpload(res)
            }
          })
          .catch(エラー => {
            コンソール.log(エラー)
          })
      },
      //顔写真をアップロード setFileUpload(res) {
        ファイルアップロードを設定する({画像: res})
          .then(res => {
            this.filePath = res.retData.filePath
            this.deleteData.imagePath = res.retData.imagePath
            ユーザーカードを追加します({ユーザーID: this.deleteData.userid、カードタイプ: this.deleteData.cardType、ユーザー監査情報: res.retData.imagePath})
              .then(res => {
                this.$message({メッセージ: res.retInfo、タイプ: "成功"})
                //データの更新に使用します。このメソッドは this.getInfo() を表示しません。
              })
              .catch(エラー => {
                コンソール.log(エラー)
              })
          })
          .catch(エラー => {
            コンソール.log(エラー)
          })
      },
      //base64に変換
      getBase64(ファイル) {
        新しいPromise(function(resolve,reject))を返す{
          リーダーを新しいFileReader()にします。
          imgResult = "" とします。
          reader.readAsDataURL(ファイル);
          reader.onload = 関数(){
            imgResult = reader.result;
          };
          reader.onerror = 関数 (エラー) {
            拒否(エラー);
          };
          reader.onloadend = 関数(){
            解決(imgResult);
          };
        });
      },
      //顔写真を削除する deleteUploadFile() {
        this.$confirm(`削除を確認しますか?`, 'prompt', {
          confirmButtonText: '確認'、
          cancelButtonText: 'キャンセル'、
          タイプ: '警告'
        }).then(() => {
          ファイルアップロードを削除します({id: this.deleteData.id, ファイルパス: this.deleteData.imagePath})
            .then(res => {
              this.$message({メッセージ: res.retInfo、タイプ: "成功"})
              this.filePath = require('@/assets/images/null.png')
              this.deleteData.imagePath = ''
            })
            .catch(エラー => {
              コンソール.log(エラー)
            })
        }).catch(() => {});
      },
      //ダイアログポップアップウィンドウをキャンセルし、アップロードされた顔写真を取得します dialogCancleCamera(str, filePath, imagePath) {
        this.dialogVisible = str
        // this.houseInfo.filePath = ファイルパス
        // this.houseInfo.userAuditInfo = イメージパス
        this.filePath = ファイルパス
        this.deleteData.imagePath = 画像パス
        この.getInfo()
      }, 
 }
  }
</スクリプト> 

<スタイル スコープ="スコープ">
  .アップロードボタン{
    位置: 相対的;
    マージン: 20px 12px 0 0;
    テキスト配置: 右;
  }
  入力#ユーザー監査情報 {
    位置: 絶対;
    表示: インラインブロック;
    幅: 80ピクセル;
    高さ: 32px;
    上: 0;
    カーソル: ポインタ;
    フォントサイズ: 0;
    Zインデックス: -1;
    /*不透明度: 0;*/
  }
  .delete-btn {
    位置: 絶対;
    上: -6px;
    右: -6px;
    表示: インラインブロック;
    幅: 16px;
    高さ: 16px;
    行の高さ: 14px;
    背景: rgba(251, 135, 66, 1);
    境界線の半径: 8px;
    テキスト配置: 中央;
    フォントサイズ: 12px;
    色: #fff;
    カーソル: ポインタ;
  }
</スタイル>

上記はあくまで参考であり、具体的な操作は実際のニーズに応じて調整する必要があります。

以上がこの記事の全内容です。皆様の勉強のお役に立てれば幸いです。また、123WORDPRESS.COM を応援していただければ幸いです。

以下もご興味があるかもしれません:
  • Vue は PC カメラを呼び出してリアルタイムで写真を撮る機能を実装します
  • Vueはコンピュータカメラを呼び出して写真機能を実現します
  • Vueはローカルカメラを呼び出して写真機能を実現します
  • Vue2.0はカメラを呼び出して写真を撮る機能を実装し、exif.jsは写真アップロード機能を実装します。
  • Vueはカメラを呼び出して写真を撮り、ローカルに保存します

<<:  MySQL 8.0 のデフォルトのデータディレクトリを変更する (設定なしの簡単な操作)

>>:  TeamCenter12 にログインする際の 404/503 問題の解決方法

推薦する

CSS の :focus-within の楽しさについて簡単に説明します

Bステーションでパスワードを入力するときに目を覆っているこの画像を見たことがある人もいると思いますこ...

MySQLデータベース移行におけるデータ文字化けの問題を解決する

リーダーの指示のもと、Java プロジェクトを引き継ぎ、リファクタリングを行う必要がありました。同時...

MySQL Limitパフォーマンス最適化とページングデータパフォーマンス最適化の詳細な説明

MySQL Limit はセグメント内のデータベース データをクエリでき、主にページングで使用されま...

ウェブページでコンテンツを引用するためによく使われるHTMLタグをマスターする

長い引用には blockquote を、短い引用には q を、参考文献には cite を使用します。...

フレックスボックスレイアウトの最終行の左揃えの実装アイデア

フレックスレイアウトを使用すると、9つの正方形のグリッドであれば、図に示すように均等に分割できます。...

MySQLの日次統計レポートでは、その日にデータがない場合には0が入力されます。

1. 問題の再現:各日の合計数を日ごとにカウントします。データのない日がある場合、グループ化によっ...

カルーセル例の JavaScript 実装

この記事では、カルーセルの効果を実現するためのJavaScriptの具体的なコードを参考までに共有し...

K8Sの5つのコントローラーの紹介と使用

目次k8sのコントローラータイプポッドとコントローラの関係デプロイメント(ステートレスアプリケーショ...

Win10 + Ubuntu 16.04 デュアルシステム 完璧なインストールチュートリアル [詳細]

必ずデータをバックアップすることを忘れないでください。データは貴重なものです! ! !コンピュータモ...

Linux サーバーの状態を監視する方法

私たち、特に Linux エンジニアは毎日 Linux サーバーを扱っています。サーバーのセキュリテ...

Vueは動的に生成されたコンポーネントをドラッグアンドドロップする要件を実装します

目次製品要件アイデア問題ライブラリ選択をドラッグコンポーネントを生成する方法コンポーネントを生成する...

ドラッグアンドドロップによる並べ替えの詳細を実現する js

目次1. はじめに2. 実装3. HTML ドラッグ アンド ドロップ API を使用しないのはなぜ...

Vueはページdivボックスのドラッグアンドドロップソート機能を実装します

vue は、ページ上の div ボックスのドラッグ アンド ドロップ ソート機能を実装します。 序文...

js ドラッグ アンド ドロップ テーブルでコンテンツ計算を実現する

この記事の例では、コンテンツの計算を実現するためのjsドラッグアンドドロップテーブルの具体的なコード...

JavaScript の高度なクロージャの説明

目次1. 閉鎖の概念追加の知識ポイント: 2. 閉鎖の役割: 3. 閉鎖例3.1 liをクリックする...