学生向けプログラミング入門 | 無料

学生向けにプログラミングを無料で解説。Java、C++、Ruby、PHP、データベース、Ruby on Rails, Python, Django

Django3.2 | クラウドソーシングアプリの構築 | 43 | 配達写真撮影

↓↓クリックして頂けると励みになります。


42 | 配達写真ページ】 << 【ホーム】 >> 【44 | 配送写真アップロード


「core/static」フォルダに「js」フォルダを新規作成します。
作成した「core/static/js」フォルダに「webcam-easy.min.js」ファイルを新規作成します。



新規作成 【Desktop/crowdsource/core/static/js/webcam-easy.min.js】

class Webcam{constructor(e,t="user",s=null,i=null){this._webcamElement=e,this._webcamElement.width=this._webcamElement.width||640,this._webcamElement.height=this._webcamElement.height||.75*this._webcamElement.width,this._facingMode=t,this._webcamList=[],this._streamList=[],this._selectedDeviceId="",this._canvasElement=s,this._snapSoundElement=i}get facingMode(){return this._facingMode}set facingMode(e){this._facingMode=e}get webcamList(){return this._webcamList}get webcamCount(){return this._webcamList.length}get selectedDeviceId(){return this._selectedDeviceId}getVideoInputs(e){return this._webcamList=[],e.forEach(e=>{"videoinput"===e.kind&&this._webcamList.push(e)}),1==this._webcamList.length&&(this._facingMode="user"),this._webcamList}getMediaConstraints(){var e={};return""==this._selectedDeviceId?e.facingMode=this._facingMode:e.deviceId={exact:this._selectedDeviceId},{video:e,audio:!1}}selectCamera(){for(let e of this._webcamList)if("user"==this._facingMode&&e.label.toLowerCase().includes("front")||"enviroment"==this._facingMode&&e.label.toLowerCase().includes("back")){this._selectedDeviceId=e.deviceId;break}}flip(){this._facingMode="user"==this._facingMode?"enviroment":"user",this._webcamElement.style.transform="",this.selectCamera()}async start(e=!0){return new Promise((t,s)=>{this.stop(),navigator.mediaDevices.getUserMedia(this.getMediaConstraints()).then(i=>{this._streamList.push(i),this.info().then(i=>{this.selectCamera(),e?this.stream().then(e=>{t(this._facingMode)}).catch(e=>{s(e)}):t(this._selectedDeviceId)}).catch(e=>{s(e)})}).catch(e=>{s(e)})})}async info(){return new Promise((e,t)=>{navigator.mediaDevices.enumerateDevices().then(t=>{this.getVideoInputs(t),e(this._webcamList)}).catch(e=>{t(e)})})}async stream(){return new Promise((e,t)=>{navigator.mediaDevices.getUserMedia(this.getMediaConstraints()).then(t=>{this._streamList.push(t),this._webcamElement.srcObject=t,"user"==this._facingMode&&(this._webcamElement.style.transform="scale(-1,1)"),this._webcamElement.play(),e(this._facingMode)}).catch(e=>{console.log(e),t(e)})})}stop(){this._streamList.forEach(e=>{e.getTracks().forEach(e=>{e.stop()})})}snap(){if(null!=this._canvasElement){null!=this._snapSoundElement&&this._snapSoundElement.play(),this._canvasElement.height=this._webcamElement.scrollHeight,this._canvasElement.width=this._webcamElement.scrollWidth;let e=this._canvasElement.getContext("2d");return"user"==this._facingMode&&(e.translate(this._canvasElement.width,0),e.scale(-1,1)),e.clearRect(0,0,this._canvasElement.width,this._canvasElement.height),e.drawImage(this._webcamElement,0,0,this._canvasElement.width,this._canvasElement.height),this._canvasElement.toDataURL("image/png")}throw"canvas element is missing"}}



記述編集 【Desktop/crowdsource/core/templates/courier/current_job_take_photo.html】

{% extends 'courier/base.html' %}
{% load static %}

{% block head %}
<script src="{% static 'js/webcam-easy.min.js' %}"></script>
<style>
  body {
    background-color: black;
  }

  .btn-back {
    position: fixed;
    top: 30px;
    left: 30px;
  }

  .buttons {
    position: fixed;
    bottom: 20px;
    left: 0;
    right: 0;
    text-align: center;
  }

  #take-photo-step {
    height: 100%;
    display: flex;
    align-items: center;
  }

  video {
    width: 100%;
    height: auto;
  }

  #upload-step {
    height: 100%;
    display: none;
    align-items: center;
  }  

</style>

{% endblock %}

{% block content %}

<div id="upload-step">
    <img id="photo">
    <div class="buttons">
      <a id="retake-button" class="btn btn-light" href="javascript:void(retake_photo())">再度撮影</a>
      <a id="upload-button" class="btn btn-info" href="javascript:void(upload_photo())">
        アップロード
      </a>
    </div>
  </div>

<div id="take-photo-step">
  <video id="webcam" autoplay playsinline></video>
  <canvas id="canvas" class="d-none"></canvas>

  <a href="{% url 'courier:current_job' %}" class="btn-back">
    <i class="fas fa-chevron-left text-light"></i>
  </a>

  <div class="buttons">
    <a href="javascript:void(take_photo())" class="btn btn-info">
      配達の写真を撮影する
    </a>
  </div>
</div>

<script>
    const webcamElement = document.getElementById('webcam');
    const canvasElement = document.getElementById('canvas');
    const webcam = new Webcam(webcamElement, 'environment', canvasElement);
    webcam.start();
  
    function take_photo() {
      let picture = webcam.snap();
      console.log(picture);

        $("#photo").attr("src", picture);
        $("#take-photo-step").css("display", "none");
        $("#upload-step").css("display", "flex");

    }
  
    function retake_photo() {
        $("#upload-step").css("display", "none");
        $("#take-photo-step").css("display", "flex");
    }

    
  </script>

{% endblock %}



写真撮影、再撮影ができるようになりました。
JsonViewのコンソールを開いて動作を確認してください。

動作確認
動作確認


↓↓クリックして頂けると励みになります。


42 | 配達写真ページ】 << 【ホーム】 >> 【44 | 配送写真アップロード