Делайте фотографии и управляйте настройками камеры

Miguel Casas-Sanchez
Франсуа Бофор
François Beaufort

Image Capture — это API для захвата неподвижных изображений и настройки параметров оборудования камеры. Этот API доступен в Chrome 59 на Android и настольных компьютерах. Мы также опубликовали библиотеку полифилов ImageCapture .

API позволяет управлять такими функциями камеры, как масштабирование, яркость, контрастность, ISO и баланс белого. Самое приятное то, что Image Capture позволяет вам получить доступ к возможностям любого доступного устройства или веб-камеры в полном разрешении. Предыдущие методы фотосъемки в Интернете использовали видеофрагменты с более низким разрешением, чем доступные для неподвижных изображений.

Объект ImageCapture создается с использованием MediaStreamTrack в качестве источника. API имеет два метода захвата takePhoto() и grabFrame() , а также способы получения возможностей и настроек камеры и изменения этих настроек.

Строительство

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);
}

Вы можете опробовать этот код из консоли DevTools.

Захватывать

Захват можно выполнить двумя способами: полный кадр и быстрый снимок. 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 , тогда как подавление эффекта красных глаз, если оно установлено, применяется только при съемке фотографии.

Возможностями и настройками «живой» камеры можно управлять посредством предварительного просмотра MediaStreamTrack : MediaStreamTrack.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 , который обеспечивает доступ к доступным возможностям «неживой» камеры. Соответственно, начиная с 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));

��астройка

«Живые» настройки камеры можно настроить с помощью ограничений applyConstraints() предварительного просмотра MediaStreamTrack , например:

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

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

Настройки «Неживой» камеры настраиваются с помощью дополнительного словаря PhotoSettings функции takePhoto() , например:

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() просто берет следующий доступный VideoFrame в MediaStreamTrack внутри процесса рендеринга, тогда как takePhoto() прерывает MediaStream , перенастраивает камеру, делает фотографию (обычно в сжатом формате, следовательно, Blob ), а затем возобновляет MediaStreamTrack . По сути, это означает, что takePhoto() предоставляет доступ ко всем возможностям камеры по разрешению неподвижных изображений. Раньше «сделать фотографию» можно было только путем вызова drawImage() для элемента canvas , используя видео в качестве источника (как в примере здесь ).

Более подробную информацию можно найти в разделе README.md.

В этой демонстрации размеры <canvas> установлены в соответствии с разрешением видеопотока, тогда как естественный размер <img> — это максимальное разрешение неподвижного изображения камеры. CSS, конечно, используется для установки размера отображения обоих.

Полный диапазон доступных разрешений камеры для неподвижных изображений можно получить и установить с помощью значений MediaSettingsRange для PhotoCapabilities.imageHeight и imageWidth . Обратите внимание, что минимальные и максимальные ограничения ширины и высоты для getUserMedia() предназначены для видео, что (как обсуждалось) может отличаться от возможностей камеры для неподвижных изображений. Другими словами, вы не сможете ��олучить доступ ко всем возможностям вашего устройства при сохранении из getUserMedia() на холст. Д��монстрация ��граничения ��азрешения WebRTC показывает, как установить ограничения getUserMedia() для разрешения.

Что-нибудь еще?

  • API обнаружения формы хорошо работает с Image Capture: grabFrame() можно вызывать повторно для передачи изображений ImageBitmap в FaceDetector или BarcodeDetector . Узнайте больше об API из записи в блоге Пола Кинлана.

  • Доступ к вспышке камеры (подсветке устройства) можно получить через FillLightMode в PhotoCapabilities , а режим Torch (постоянно включенная вспышка) можно найти в MediaTrackCapabilities .

Демо и примеры кода

Поддерживать

  • Chrome 59 на Android и компьютере.
  • Chrome Canary на Android и настольных компьютерах до версии 59 с включенными функциями экспериментальной веб-платформы .

Узнать больше