世界杯赔率_男乒世界杯决赛 - fjpftz.com

HOME> 贝利世界杯> 使用 getUserMedia() 拍摄静态照片

使用 getUserMedia() 拍摄静态照片

2026-01-11 11:10:41

HTML 标记

我们的 HTML 界面有两个主要的操作部分:流和捕获面板以及演示面板。它们俩都在它们自己的

中并排渲染,以便于添加样式和控制。

左边的面板包含两个组件:一个

这很简单,当我们进入 JavaScript 代码时,我们将看到它们是如何紧密联系在一起的。

接下来,我们有一个 元素,捕获的帧被存储到其中,可能以某种方式进行操作,然后转换为输出图像文件。通过使用样式 display:none 将画布保持隐藏,以避免画面的混乱——用户不需要看到这个中间过程。

我们还有一个 元素,我们将在其中绘制图像——这是让用户看到的最终显示。

html

捕获的图像会显示在这里。

这是所有相关的 HTML。其余的只是一些页面布局和提供一个返回页面链接的些许文本。

JavaScript 代码

现在来看看 JavaScript 代码。我们将把它分解成几个小的部分,使其更容易解释。

初始化

我们首先将整个脚本包装在匿名函数中,以避免使用全局变量,然后设置我们将要使用的各种变量。

js(() => {

const width = 320; // 外面会对照片的宽度进行缩放

const height = 0; // 高度会基于输入的视频流进行计算

const streaming = false;

let video = null;

let canvas = null;

let photo = null;

let startbutton = null;

这些变量分别是:

width

无论输入视频的尺寸如何,我们将把所得到的图像缩放到宽度为 320 像素。

height

给定流的 width 和宽高比,计算出图像的输出高度。

streaming

指示当前是否有活动的视频流正在运行。

video

这将是页面加载完成后对

canvas

这将是页面加载完成后对 元素的引用。

photo

这将在页面加载完成后引用 元素。

startbutton

这将引用用于触发捕获的

捕获的图像会显示在这里。

访问我们的文章:

href="https://developer.mozilla.org/zh-CN/docs/Web/API/WebRTC_API/Taking_still_photos">

使用 getUserMedia() 拍摄静态照片

>以详细了解此处使用的技术。

CSS

css#video {

border: 1px solid black;

box-shadow: 2px 2px 3px black;

width: 320px;

height: 240px;

}

#photo {

border: 1px solid black;

box-shadow: 2px 2px 3px black;

width: 320px;

height: 240px;

}

#canvas {

display: none;

}

.camera {

width: 340px;

display: inline-block;

}

.output {

width: 340px;

display: inline-block;

vertical-align: top;

}

#startbutton {

display: block;

position: relative;

margin-left: auto;

margin-right: auto;

bottom: 32px;

background-color: rgba(0, 150, 0, 0.5);

border: 1px solid rgba(255, 255, 255, 0.7);

box-shadow: 0px 0px 1px 2px rgba(0, 0, 0, 0.2);

font-size: 14px;

font-family: "Lucida Grande", "Arial", sans-serif;

color: rgba(255, 255, 255, 1);

}

.contentarea {

font-size: 16px;

font-family: "Lucida Grande", "Arial", sans-serif;

width: 760px;

}

JavaScript

js(() => {

// The width and height of the captured photo. We will set the

// width to the value defined here, but the height will be

// calculated based on the aspect ratio of the input stream.

const width = 320; // We will scale the photo width to this

let height = 0; // This will be computed based on the input stream

// |streaming| indicates whether or not we're currently streaming

// video from the camera. Obviously, we start at false.

let streaming = false;

// The various HTML elements we need to configure or control. These

// will be set by the startup() function.

let video = null;

let canvas = null;

let photo = null;

let startbutton = null;

function showViewLiveResultButton() {

if (window.self !== window.top) {

// Ensure that if our document is in a frame, we get the user

// to first open it in its own tab or window. Otherwise, it

// won't be able to request permission for camera access.

document.querySelector(".contentarea").remove();

const button = document.createElement("button");

button.textContent = "查看以上示例代码的实时演示";

document.body.append(button);

button.addEventListener("click", () => window.open(location.href));

return true;

}

return false;

}

function startup() {

if (showViewLiveResultButton()) {

return;

}

video = document.getElementById("video");

canvas = document.getElementById("canvas");

photo = document.getElementById("photo");

startbutton = document.getElementById("startbutton");

navigator.mediaDevices

.getUserMedia({ video: true, audio: false })

.then((stream) => {

video.srcObject = stream;

video.play();

})

.catch((err) => {

console.error(`An error occurred: ${err}`);

});

video.addEventListener(

"canplay",

(ev) => {

if (!streaming) {

height = video.videoHeight / (video.videoWidth / width);

// Firefox currently has a bug where the height can't be read from

// the video, so we will make assumptions if this happens.

if (isNaN(height)) {

height = width / (4 / 3);

}

video.setAttribute("width", width);

video.setAttribute("height", height);

canvas.setAttribute("width", width);

canvas.setAttribute("height", height);

streaming = true;

}

},

false,

);

startbutton.addEventListener(

"click",

(ev) => {

takepicture();

ev.preventDefault();

},

false,

);

clearphoto();

}

// Fill the photo with an indication that none has been

// captured.

function clearphoto() {

const context = canvas.getContext("2d");

context.fillStyle = "#AAA";

context.fillRect(0, 0, canvas.width, canvas.height);

const data = canvas.toDataURL("image/png");

photo.setAttribute("src", data);

}

// Capture a photo by fetching the current contents of the video

// and drawing it into a canvas, then converting that to a PNG

// format data URL. By drawing it on an offscreen canvas and then

// drawing that to the screen, we can change its size and/or apply

// other changes before drawing it.

function takepicture() {

const context = canvas.getContext("2d");

if (width && height) {

canvas.width = width;

canvas.height = height;

context.drawImage(video, 0, 0, width, height);

const data = canvas.toDataURL("image/png");

photo.setAttribute("src", data);

} else {

clearphoto();

}

}

// Set up our event listener to run the startup process

// once loading is complete.

window.addEventListener("load", startup, false);

})();

结果

过滤器的乐趣

由于我们通过从

你可以使用例如 Firefox 开发者工具的样式编辑器来播放此效果;有关如何执行此操作的详细信息,请参阅编辑 CSS 过滤器。

使用特定设备

如果需要,你可以将允许的视频源限定为特定的设备或特定的一组设备。要做到这一点,请调用 MediaDevices.enumerateDevices。若返回的 promise 兑现了一个 MediaDeviceInfo 对象(描述了可用的设备)数组,可以从中选取一个你想要允许的设备,并将对应的 deviceId 或 MediaTrackConstraints 对象的 deviceId 作为参数传入到 getUserMedia() 中。

参见

GitHub 上的示例代码

MediaDevices.getUserMedia

Canvas 教程中的使用视频帧

CanvasRenderingContext2D.drawImage()

Help improve MDN

Was this page helpful to you?

Yes

No

Learn how to contribute

This page was last modified on ⁨2024年7月27日⁩ by MDN contributors.

View this page on GitHub • Report a problem with this content

极限存在准则

[外交]定安哪里有小姐小妹提供上门全套服务

最新发表
友情链接