Robienie zdjęć i kontrolowanie ustawień aparatu

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

Image Capture to interfejs API służący do robienia zdjęć i konfigurowania ustawień aparatu. Ten interfejs API jest dostępny w Chrome 59 na urządzeniach z Androidem i komputerach. Opublikowaliśmy też bibliotekę polyfill ImageCapture.

Umożliwia on kontrolę nad takimi funkcjami aparatu jak powiększenie, jasność, kontrast, ISO i balans bieli. A co najważniejsze, funkcja Robienie zdjęć zapewnia dostęp do pełnej rozdzielczości aparatu lub kamery internetowej w pełnej rozdzielczości. Poprzednie techniki robienia zdjęć w internecie wykorzystywały zrzuty filmów o niższej rozdzielczości niż w przypadku zdjęć.

Skonstruowany jest obiekt ImageCapture, którego źródłem jest MediaStreamTrack. Interfejs API udostępnia 2 metody przechwytywania takePhoto() i grabFrame() oraz sposoby na pobranie możliwości i ustawień kamery oraz zmianę tych ustawień.

Prace budowlane

Interfejs Image Capture API uzyskuje dostęp do aparatu za pomocą identyfikatora MediaStreamTrack uzyskanego z 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);
}

Możesz wypróbować ten kod w konsoli Narzędzi deweloperskich.

Rejestruj

Przechwytywanie można wykonać na 2 sposoby: w trybie pełnoekranowym lub w ramach szybkiego zrzutu. takePhoto()zwraca wartość Blob, w wyniku pojedynczej ekspozycji zdjęcia, którą można pobrać, zapisać w przeglądarce lub wyświetlić w elemencie <img>. Ta metoda wykorzystuje najwyższą dostępną rozdzielczość aparatu fotograficznego. Na przykład:

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() zwraca obiekt ImageBitmap, migawkę obrazu na żywo, który można na przykład narysować na <canvas>, a następnie przetworzyć w celu selektywnej zmiany wartości kolorów. Pamiętaj, że ImageBitmap będzie mieć tylko rozdzielczość źródła obrazu, która zwykle jest niższa niż rozdzielczość obrazu aparatu. Na przykład:

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

Uprawnienia i ustawienia

Ustawieniami przechwytywania można zmieniać na kilka sposobów w zależności od tego, czy zmiany są odzwierciedlane w MediaStreamTrack czy są widoczne dopiero po takePhoto(). Na przykład zmiana poziomu zoom jest natychmiast wprowadzana do MediaStreamTrack, a redukcja efektu czerwonych oczu po ustawieniu jest stosowana tylko podczas robienia zdjęcia.

Możliwości i ustawienia kamery „na żywo” można zmieniać na podglądzie.MediaStreamTrack: MediaStreamTrack.getCapabilities() zwraca słownik MediaTrackCapabilities z konkretnymi obsługiwanymi funkcjami oraz zakresami i dozwolonymi wartościami, np. obsługiwanym zakresem powiększenia lub dozwolonymi trybami balansu bieli. Odpowiadając MediaStreamTrack.getSettings(), zwraca MediaTrackSettings z konkretnymi bieżącymi ustawieniami. Do tej kategorii należą: powiększenie, jasność i tryb latarki,

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

Możliwości i ustawienia kamery „nieaktywna” są zmieniane za pomocą obiektu ImageCapture: ImageCapture.getPhotoCapabilities() zwraca obiekt PhotoCapabilities, który daje dostęp do dostępnych funkcji kamery „niedostępnych na żywo”. Począwszy od Chrome 61, ImageCapture.getPhotoSettings() zwraca obiekt PhotoSettings z konkretnymi bieżącymi ustawieniami. Do tej sekcji należą rozdzielczość zdjęcia, redukcja czerwonych oczu i tryb lampy błyskowej (z wyjątkiem latarki), na przykład:

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

Konfiguruję

Ustawienia kamery podczas transmisji można skonfigurować w MediaStreamTrack applyConstraints() ograniczeniach, na przykład:

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

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

Ustawienia kamery „nieaktywna” są skonfigurowane przy użyciu opcjonalnego słownika PhotoSettings urządzenia takePhoto(), na przykład:

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

Funkcje aparatu

Jeśli uruchomisz powyższy kod, zauważysz różnicę w wymiarach między wynikami grabFrame() i takePhoto().

Metoda takePhoto() zapewnia dostęp do maksymalnej rozdzielczości kamery.

Funkcja grabFrame() po prostu pobiera następny dostępny element VideoFrame w ramach MediaStreamTrack w procesie renderowania, podczas gdy takePhoto() przerywa działanie MediaStream, ponownie konfiguruje aparat, robi zdjęcie (zwykle w formacie skompresowanym, dlatego Blob), a następnie wznawia MediaStreamTrack. W skrócie oznacza to, że takePhoto() zapewnia dostęp do pełnej rozdzielczości obrazu nieruchomego. Wcześniej można było „zrobić zdjęcie” tylko przy użyciu wywołania drawImage() w elemencie canvas przy użyciu filmu jako źródła (jak tutaj znajdziesz przykład).

Więcej informacji znajdziesz w sekcji README.md.

W tej prezentacji wymiary <canvas> są ustawione na rozdzielczość strumienia wideo, a rozmiar naturalny <img> to maksymalna rozdzielczość nieruchomego obrazu z kamery. Oczywiście do ustawiania rozmiaru ich wyświetlania używany jest CSS.

Pełny zakres dostępnych rozdzielczości aparatu dla zdjęć nieruchomych możesz pobrać i ustawić za pomocą wartości MediaSettingsRange dla właściwości PhotoCapabilities.imageHeight i imageWidth. Pamiętaj, że ograniczenia minimalnej i maksymalnej szerokości i wysokości w przypadku getUserMedia() obowiązują w przypadku filmów, co (zgodnie z omówieniem) może się różnić od możliwości aparatu w przypadku zdjęć. Oznacza to, że podczas zapisywania pliku z elementu getUserMedia() w obszarze roboczym możesz nie mieć dostępu do pełnej rozdzielczości urządzenia. Wersja demonstracyjna ograniczenia rozdzielczości WebRTC pokazuje, jak ustawić ograniczenia getUserMedia() na potrzeby rozwiązania.

Coś jeszcze?

  • Interfejs Pattern Detection dobrze działa z aplikacją Image Capture: grabFrame() może być wielokrotnie wywoływany w celu przekazywania danych z ImageBitmap do FaceDetector lub BarcodeDetector. Więcej informacji o interfejsie API znajdziesz w poście na blogu Paula Kinlana.

  • Lampa błyskowa (lampa błyskowa urządzenia) jest dostępna w FillLightMode w PhotoCapabilities, ale tryb latarki (błyskająca świecąca lampa błyskowa) znajdziesz w MediaTrackCapabilities.

Prezentacje i przykłady kodu

Pomoc

  • Chrome 59 na urządzeniach z Androidem i komputerach.
  • Chrome Canary na urządzeniach z Androidem i komputerach w wersjach starszych niż 59 z włączonymi funkcjami eksperymentalnej platformy internetowej.

Więcej informacji