Skip to content

JavaScript 调用相机并拍照

Posted on:2020年12月14日 at 19:42

Start

<button id="takePhoto">takePhoto</button>
<div id="app"></div>
class Camera {
  constructor(root, width = 480, height = 320) {
    this.root = root;
    this.width = width;
    this.height = height;
    this.video = null;
    this.canvas = null;
    this.canvasCtx = null;
    this.stream = null;
    this.photo = [];
    this.init();
  }

  init() {
    const constraints = {
      video: {
        width: this.width,
        height: this.height,
      },
    };
    navigator.mediaDevices
      .getUserMedia(constraints)
      .then(stream => {
        this.mount(stream);
      })
      .catch(error => {
        console.log(error);
        alert("打开相机失败");
      });
  }

  mount(stream) {
    const video = document.createElement("video");
    const canvas = document.createElement("canvas");
    video.width = this.width;
    video.height = this.height;
    video.style.display = "block";
    video.autoplay = "autoplay";
    video.srcObject = stream;
    canvas.width = this.width;
    canvas.height = this.height;
    this.video = video;
    this.canvas = canvas;
    this.canvasCtx = canvas.getContext("2d");

    if (!this.root) {
      document.body.appendChild(this.video);
      return false;
    }
    if (typeof this.root === "string") {
      this.root = document.querySelector(this.root);
    }
    this.root.appendChild(this.video);
  }

  takePhotos(showPhoto) {
    if (!this.canvas) return "";
    this.canvasCtx.drawImage(this.video, 0, 0, this.width, this.height);
    const base64 = this.canvas.toDataURL("image/jpg");
    if (showPhoto) {
      const wrapper = document.createElement("div");
      wrapper.style.position = "relative";
      wrapper.style.display = "inline-block";
      const image = new Image();
      image.style.display = "block";
      image.src = base64;
      const download = document.createElement("a");
      download.setAttribute("download", `${Date.now()}.jpg`);
      download.innerText = "下载照片";
      download.href = base64;
      download.style.position = "absolute";
      download.style.top = "0px";
      download.style.right = "0px";

      wrapper.appendChild(image);
      wrapper.appendChild(download);

      if (!this.root) {
        document.body.appendChild(wrapper);
      } else {
        this.root.appendChild(wrapper);
      }
    }
    this.photo.push(base64);
    return base64;
  }
}

usage

const camera = new Camera();

const takePhoto = document.querySelector("#takePhoto");
takePhoto.addEventListener("click", function () {
  camera.takePhotos(true);
});