JS打开摄像头并截图上传示例

要实现JS打开摄像头并截图上传的功能,可以使用HTML5提供的MediaDevices.getUserMedia方法获取用户的媒体设备(如摄像头),再借助Canvas API将摄像头捕捉到的图像绘制到Canvas上,最后将Canvas上的图像数据转换为base64编码,便于上传至服务器。

以下是一条实现步骤较为详细的示例说明:

示例1:基本实现

HTML

<div>
  <video id="camera-video" autoplay></video>
  <button id="take-screenshot" onclick="takeScreenshot()">截图上传</button>
  <canvas id="canvas" style="display:none;"></canvas>
</div>

在HTML中,我们创建了一个<video>标签用于显示摄像头捕捉到的实时视频流,一个“截图上传”按钮,以及一个用于绘制图像的<canvas>标签。<canvas>标签的CSS属性中设置了display:none;表示不在页面中显示Canvas标签。

JS

const video = document.getElementById('camera-video');
const canvas = document.getElementById('canvas');
const screenshotBtn = document.getElementById('take-screenshot');

function initCamera() {
  navigator.mediaDevices.getUserMedia({video: true})
    .then((stream) => {
      video.srcObject = stream;
      video.play();
    })
    .catch((err) => {
      console.log(`Camera initialization failed with error: ${err}`);
    });
}

function takeScreenshot() {
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
  const imgData = canvas.toDataURL('image/png');
  // Use imgData for uploading to server or showing in HTML
}

在JS代码中,我们获取了视频、Canvas、以及“截图上传”按钮的DOM元素,并使用navigator.mediaDevices.getUserMedia()方法获取了用户的媒体设备流。video.srcObject = stream;语句将获取到的视频流赋值给<video>元素的srcObject属性,触发浏览器对摄像头视频流的捕捉并实时播放。takeScreenshot()函数获取<canvas>元素的绘图上下文(Context),将摄像头捕捉到的视频帧绘制到Canvas上,最后通过canvas.toDataURL()方法将Canvas图像数据转为base64编码的字符串格式,以便于上传至服务器或在HTML页面中显示。

示例2:增加用户授权提示

在示例1的基础上,为了避免打开摄像头时未经用户授权而导致的授权失败,我们需要在获取用户媒体设备前先显示授权提示框,让用户明确授权后再进行获取。以下是相应的示例代码:

HTML

<div>
  <video id="camera-video" autoplay></video>
  <button id="take-screenshot" onclick="takeScreenshot()">截图上传</button>
  <canvas id="canvas" style="display:none;"></canvas>
</div>

HTML部分与示例1相同,不再重复说明。

JS

const video = document.getElementById('camera-video');
const canvas = document.getElementById('canvas');
const screenshotBtn = document.getElementById('take-screenshot');

function requestUserMedia() {
  const constraints = {video: true};
  if(navigator.mediaDevices.getUserMedia) { // Standard API
    return navigator.mediaDevices.getUserMedia(constraints);
  } else if(navigator.getUserMedia) { // Old API
    const getUserMedia = promisify(navigator.getUserMedia, navigator);
    return getUserMedia(constraints);
  } else {
    alert('getUserMedia is not supported in this browser.');
    return Promise.reject();
  }
}

function promisify(fn, context) {
  return function() {
    const args = Array.from(arguments);
    return new Promise((resolve, reject) => {
      const callback = function(result) {
        resolve(result);
      };
      args.push(callback);
      fn.apply(context, args);
    });
  };
}

function initCamera() {
  requestUserMedia()
    .then((stream) => {
      video.srcObject = stream;
      video.play();
    })
    .catch((err) => {
      console.log(`Camera initialization failed with error: ${err}`);
    });
}

function takeScreenshot() {
  canvas.width = video.videoWidth;
  canvas.height = video.videoHeight;
  canvas.getContext('2d').drawImage(video, 0, 0, canvas.width, canvas.height);
  const imgData = canvas.toDataURL('image/png');
  // Use imgData for uploading to server or showing in HTML
}

在JS代码中,我们先定义了一个用于获取用户媒体设备流的函数requestUserMedia(),该函数使用了Promise机制,可以适配新旧两种版本的getUserMedia API。promisify()函数用于将callback式的老版本API转换为Promise式适用于Promise机制的使用,从而保证兼容性。initCamera()函数中,我们使用了之前定义的requestUserMedia()函数替代了之前的navigator.mediaDevices.getUserMedia()方法,从而在获取摄像头流之前弹出授权提示框。其余代码与示例1相同。

需要注意的是,在Chrome等新版浏览器中,用户授权提示不再是弹出浏览器窗口,而是出现在浏览器当前页上方。

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:JS打开摄像头并截图上传示例 - Python技术站

(0)
上一篇 2023年6月11日
下一篇 2023年6月11日

相关文章

  • 无语,javascript居然支持中文(unicode)编程!

    当我看到 “无语,JavaScript居然支持中文(Unicode)编程!” 这句话时,我相信说的是JavaScript支持使用Unicode字符作为标识符。这意味着您可以在JavaScript编程时使用中文或其他unicode字符,这对特定项目或程序员可能很有用。 下面是使用JavaScript中文(Unicode)标识符的完整攻略。 使用Unicode字…

    JavaScript 2023年5月19日
    00
  • javascript学习笔记(七) js函数介绍

    JavaScript学习笔记(七) – JavaScript函数介绍 什么是函数 函数是一个可预测的、可重用的代码块,用于实现特定的任务。函数是 JavaScript 的一等公民,因此它们可以像任何其他值一样传递和赋值。 函数声明和调用 使用 function 关键字来声明一个函数。下面是一个简单的函数声明示例: function sayHello() { …

    JavaScript 2023年5月18日
    00
  • 现代 javscript 编程 资料

    现代 JavaScript 编程资料攻略 JavaScript 是一门非常流行的编程语言,它的应用广泛,包括 Web 前端开发、后端开发、移动端应用开发等。随着 JavaScript 的发展,现代 JavaScript 编程已经成为了一个新的概念,它包括了许多新的语言特性和工具,如 ES6、TypeScript、Vue、React 等。本文旨在为大家提供一个…

    JavaScript 2023年5月18日
    00
  • 中级前端工程师必须要掌握的27个JavaScript 技巧(干货总结)

    下面是“中级前端工程师必须要掌握的27个JavaScript 技巧(干货总结)”的完整攻略: 1. 确保函数只被运行一次 有时候我们需要一个函数只能运行一次,比如在页面中只能打开一次弹窗。这时可以利用闭包来实现。 var runOnce = (function() { var executed = false; return function() { if …

    JavaScript 2023年5月28日
    00
  • node环境执行js文件的完整步骤

    下面是Node环境执行JavaScript文件的完整步骤的攻略: 步骤1:安装node.js 要在Node环境中执行JavaScript文件,需要先安装Node.js运行环境。可在官网下载对应版本的Node.js,并进行安装。 步骤2:创建JavaScript文件 创建一个.js文件,编写JavaScript代码,并存储到本地目录中。例如,创建一个Hello…

    JavaScript 2023年5月27日
    00
  • JavaScript定时器原理详解

    JavaScript定时器原理详解 定时器基本概念 在JavaScript中,我们经常需要在一个间隔时间内循环执行某些任务或在某个时间点执行某些任务,这就需要用到定时器。 在JavaScript中,定时器有两种类型:setInterval和setTimeout,它们都是由浏览器提供的全局函数。 setInterval定时器可以按照一定的时间间隔执行代码,而s…

    JavaScript 2023年5月27日
    00
  • JavaScript中最容易混淆的作用域、提升、闭包知识详解(推荐)

    JavaScript中最容易混淆的作用域、提升、闭包知识详解 作用域 JavaScript采用词法作用域,即函数的作用域在函数定义时就已经确定了,不会随着函数调用的位置改变。因此,JavaScript中存在全局作用域和函数作用域。 全局作用域 全局作用域是指在代码的任何位置都可以访问的变量、函数和对象,它是在所有函数外部定义的作用域。 以下是一个示例,全局作…

    JavaScript 2023年5月28日
    00
  • javascript工具库代码

    让我详细讲解一下JavaScript工具库代码的完整攻略。 什么是JavaScript工具库代码? JavaScript工具库代码是已经封装好的JavaScript函数或类,它们帮助我们实现一些常见业务场景和功能,节省了开发者自行编写这些功能代码的时间和精力,提高了开发效率。 如何使用JavaScript工具库代码? 使用JavaScript工具库代码可以通…

    JavaScript 2023年5月18日
    00
合作推广
合作推广
分享本页
返回顶部