拍摄照片和控制相机设置

Miguel Casas-Sanchez
François Beaufort
François Beaufort

Image Capture 是一个用于拍摄静态图像并配置相机硬件的 API 设置。此 API 可在 Android 设备和桌面设备上的 Chrome 59 中使用。我们还 发布了 ImageCapture polyfill 库

该 API 可让您控制相机功能,例如变焦、亮度 对比度、ISO 和白平衡最棒的是,图片拍摄 任何可用设备上的相机或网络摄像头的完整分辨率功能。 以往的网上拍照技术使用视频快照, 其分辨率低于静态图片的分辨率。

ImageCapture 对象是使用 MediaStreamTrack 作为源构建的。通过 然后,API 有两个捕获方法 takePhoto()grabFrame(),以及 检索相机的功能和设置,并更改这些设置 设置。

施工

Image Capture API 通过获取的 MediaStreamTrack 访问相机 来自getUserMedia()

navigator.mediaDevices.getUserMedia({video: true})
    .then(gotMedia)
    .catch(error => console.error('getUserMedia() error:', error));

function gotMedia(mediaStream) {
    const mediaStreamTrack = mediaStream.getVideoTracks()[0];
    const imageCapture = new ImageCapture(mediaStreamTrack);
    console.log(imageCapture);
}

您可以在开发者工具控制台中试用此代码。

捕获

拍摄方法有两种:全帧拍摄和快速拍摄快照。takePhoto() 返回 Blob,即单次摄影曝光的结果; 该文件可下载、由浏览器存储或显示在<img>中 元素。此方法会使用可用的最高相机分辨率。 例如:

const img = document.querySelector('img');
// ...
imageCapture.takePhoto()
    .then(blob => {
    img.src = URL.createObjectURL(blob);
    img.onload = () => { URL.revokeObjectURL(this.src); }
    })
    .catch(error => console.error('takePhoto() error:', error));

grabFrame() 会返回一个 ImageBitmap 对象,即直播视频的快照, 它可(例如)绘制在 <canvas>并进行后期处理 选择性地更改颜色值。请注意,ImageBitmap 仅使用 视频源的分辨率 - 通常低于摄像机的 静态图片功能。例如:

const canvas = document.querySelector('canvas');
// ...
imageCapture.grabFrame()
    .then(imageBitmap => {
    canvas.width = imageBitmap.width;
    canvas.height = imageBitmap.height;
    canvas.getContext('2d').drawImage(imageBitmap, 0, 0);
    })
    .catch(error => console.error('grabFrame() error:', error));

功能和设置

您可以通过多种方式操纵拍摄设置,具体取决于 是让更改体现在 MediaStreamTrack中,还是只能 takePhoto()之后出现。例如,zoom 级别的变化会立即生效 会传播到 MediaStreamTrack,而消除红眼(如果已设置) 仅在拍照时适用。

“直播”相机功能和设置通过预览版操纵 MediaStreamTrackMediaStreamTrack.getCapabilities() 返回 MediaTrackCapabilities 包含具体支持的功能、范围或允许的 值,例如支持的缩放范围或允许的白平衡模式。 相应地,MediaStreamTrack.getSettings() 会返回 MediaTrackSettings 并采用具体的当前设置缩放、亮度和手电筒模式 此类别,例如:

var zoomSlider = document.querySelector('input[type=range]');
// ...
const capabilities = mediaStreamTrack.getCapabilities();
const settings = mediaStreamTrack.getSettings();
if (capabilities.zoom) {
    zoomSlider.min = capabilities.zoom.min;
    zoomSlider.max = capabilities.zoom.max;
    zoomSlider.step = capabilities.zoom.step;
    zoomSlider.value = settings.zoom;
}

“非直播”您可以通过 ImageCapture 对象:ImageCapture.getPhotoCapabilities() 会返回 PhotoCapabilities 该对象可提供对“Non-Live”的访问可用的相机功能。 相应地,从 Chrome 61 开始,ImageCapture.getPhotoSettings() 返回一个 PhotoSettings 对象具有具体的当前设置。照片分辨率,红眼 缩减和闪光灯模式(手电筒除外)属于此部分,例如:

var widthSlider = document.querySelector('input[type=range]');
// ...
imageCapture.getPhotoCapabilities()
    .then(function(photoCapabilities) {
    widthSlider.min = photoCapabilities.imageWidth.min;
    widthSlider.max = photoCapabilities.imageWidth.max;
    widthSlider.step = photoCapabilities.imageWidth.step;
    return imageCapture.getPhotoSettings();
    })
    .then(function(photoSettings) {
    widthSlider.value = photoSettings.imageWidth;
    })
    .catch(error => console.error('Error getting camera capabilities and settings:', error));

正在配置

“直播”可通过预览来配置相机设置 MediaStreamTrackapplyConstraints() 限制条件 ,例如:

var zoomSlider = document.querySelector('input[type=range]');

mediaStreamTrack.applyConstraints({ advanced: [{ zoom: zoomSlider.value }]})
    .catch(error => console.error('Uh, oh, applyConstraints() error:', error));

“非直播”摄像头设置是使用 takePhoto() 的可选功能配置的 PhotoSettings 字典,例如:

var widthSlider = document.querySelector('input[type=range]');
imageCapture.takePhoto({ imageWidth : widthSlider.value })
    .then(blob => {
    img.src = URL.createObjectURL(blob);
    img.onload = () => { URL.revokeObjectURL(this.src); }
    })
    .catch(error => console.error('Uh, oh, takePhoto() error:', error));

相机功能

如果您运行上面的代码,会注意到 grabFrame()takePhoto() 条结果。

takePhoto() 方法提供对相机最大分辨率的访问权限。

grabFrame() 只需要 MediaStreamTrack 中的下一个可用VideoFrametakePhoto() 会中断 MediaStream, 重新配置相机,拍摄照片(通常采用压缩格式, 因此需要 Blob),然后恢复 MediaStreamTrack。从本质上来讲, takePhoto() 授予对完整静态图片分辨率的访问权限 相机的功能。以前,您只能“拍照”作者: 对 canvas 元素调用 drawImage(),使用视频作为源(根据 请点击此处查看示例)。

如需了解详情,请参阅 README.md 部分

在此演示中,<canvas> 尺寸设为视频的分辨率 而 <img> 的自然尺寸是最大的静态图片尺寸 相机的分辨率。当然,CSS 用于设置 两者的两种尺寸

可以获取和设置静态图像的所有可用相机分辨率 使用 PhotoCapabilities.imageHeightMediaSettingsRange 值和 imageWidth。请注意, getUserMedia() 适用于视频,(如前所述)可能不同于 相机功能(适用于静态图片)。也就是说,您可能无法 在保存时访问设备的完整分辨率功能 getUserMedia()附加到画布。WebRTC 分辨率限制条件演示 展示了如何为分辨率设置 getUserMedia() 约束条件。

还想执行任何其他步骤吗?

  • Shape Detection API 与图片拍摄搭配使用效果好:可反复调用 grabFrame() 来提供图片 将 ImageBitmap 转换为 FaceDetectorBarcodeDetector。详细了解 API 摘自 Paul Kinlan 的博文

  • 相机闪光灯(设备指示灯)可通过以下方式访问: FillLightMode 英寸 PhotoCapabilities ,不过您可以在以下位置找到手电筒模式(持续闪光灯) MediaTrackCapabilities

演示和代码示例

支持

  • Android 和桌面设备上的 Chrome 59。
  • Android 和桌面版 Chrome Canary 59 之前的版本, 已启用实验性网络平台功能。

了解详情