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

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 с включенными функциями экспериментальной веб-платформы .

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