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 問題の解決方法

推薦する

nginx の http リクエスト処理の各段階の詳細な分析

nginx の HTTP モジュールを作成する場合、リクエスト開始時のアクセス許可の有無、コンテンツ...

HTML で点線の境界線を設定する方法

CSSスタイルとHTMLタグ要素を使用するさまざまな HTML タグに点線の境界線を追加するために、...

詳細なアイデアを備えたシンプルな計算機の HTML 実装

コードをコピーコードは次のとおりです。 <!DOCTYPE html> <html...

Win2008 R2 mysql 5.5 zip 形式 mysql のインストールと設定

Win2008 R2 zip形式のMySQLのインストールと設定1. Baidu MySQL 5.6...

MySQL REVOKE でユーザー権限を削除する

MySQL では、REVOKE ステートメントを使用してユーザーの特定の権限を削除できます (ユーザ...

MySQL sql_modeクエリと設定の詳細な説明

1. SQLを実行して表示する @@session.sql_mode を選択します。 グローバルレベ...

MySQL に IP アドレスを効果的に保存する方法と、文字列 IP と数値を変換する方法の詳細な説明

High Performance MySQL バージョン 3 (セクション 4.1.7) を見ると、...

Nginx操作応答ヘッダー情報の実装

前提条件: ヘッダー情報操作をサポートするには、ngx_http_headers_module モジ...

この記事では、Vue 3.0 レスポンシブの使い方を説明します。

目次ユースケースリアクティブAPI関連プロセス反応的なcreateReactiveObjectはレス...

Docker Compose を使用して Confluence を構築するチュートリアル

この記事は「Attribution 4.0 International (CC BY 4.0)」ライ...

MySqlを最適化するためにnot inを使用する方法

最近、プロジェクトで選択クエリを使用する際に、未使用の主キー ID を除外するために not in ...

クリーンで美しいウェブデザインのための4つの原則

この記事では、 Webデザインに関連するこれら4 つの原則について説明します。これら4 つの原則を念...

MySQLの浅いエントリと深いエグジットの原則についての簡単な説明

目次1. ページの概要2. 下限と上限3. ページディレクトリを使用する4. ページの実際の外観4....

Docker イメージのプルとタグ操作 pull | tag

Fabric プロジェクトのソースコードを読み直してみたところ、Docker の部分でよくわからな...

mysqlを使用して、URLから返されたhttp GETリクエストデータを記録します。

ビジネスシナリオの要件と実装ロジックの分析ビジネスでは、HTTP GET を使用してデータを要求する...