Robienie zdjęć i kontrolowanie ustawień aparatu

Image Capture to interfejs API do robienia zdjęć i konfigurowania ustawień sprzętu aparatu. Interfejs API jest dostępny w Chrome 59 na Androida i komputery. Opublikowaliśmy też bibliotekę polyfill ImageCapture.

Interfejs API umożliwia sterowanie funkcjami aparatu, takimi jak zoom, jasność, kontrast, ISO i balans bieli. Co najlepsze, Image Capture umożliwia dostęp do pełnej rozdzielczości dostępnej w przypadku aparatu lub kamery internetowej. Wcześniejsze techniki robienia zdjęć w internecie polegały na robieniu zdjęć z filmu, które mają niższą rozdzielczość niż zdjęcia statyczne.

Obiekt ImageCapture jest tworzony na podstawie obiektu MediaStreamTrack. API ma 2 metody przechwytywania: takePhoto()grabFrame() oraz sposoby na pobranie możliwości i ustawień aparatu oraz na zmianę tych ustawień.

Roboty drogowe

Interfejs Image Capture API uzyskuje dostęp do aparatu za pomocą 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

Zdjęcia można robić na 2 sposoby: w pełnym kadrze i w ramach szybkiego robienia zdjęć. takePhoto()zwraca Blob, wynik pojedynczego naświetlenia fotograficznego, który 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, czyli zrzut z filmu na żywo, który może być na przykład narysowany na obiekcie <canvas>, a następnie przetworzony w celu selektywnej zmiany wartości kolorów. Pamiętaj, że ImageBitmap będzie mieć tylko rozdzielczość źródła wideo, która zwykle jest niższa niż możliwości aparatu w zakresie zdjęć. 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));

Możliwości i ustawienia

Ustawienia przechwytywania można modyfikować na kilka sposobów, w zależności od tego, czy zmiany będą widoczne w MediaStreamTrack, czy też będą widoczne dopiero po takePhoto(). Na przykład zmiana poziomu zoom jest natychmiast rozpowszechniana do MediaStreamTrack, podczas gdy redukcja efektu czerwonych oczu, jeśli jest ustawiona, jest stosowana tylko podczas robienia zdjęcia.

Funkcje i ustawienia kamery „Na żywo” są modyfikowane za pomocą podglądu: MediaStreamTrack: MediaStreamTrack.getCapabilities() zwraca słownik MediaTrackCapabilities z konkretnymi obsługiwanymi funkcjami i zakresami lub dozwolonymi wartościami, np. obsługiwany zakres zoomu lub dozwolone tryby balansu bieli. Odpowiednio MediaStreamTrack.getSettings() zwraca MediaTrackSettings z konkretnymi bieżącymi ustawieniami. Do tej kategorii należą na przykład powiększanie, 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;
}

Funkcje i ustawienia kamery „Nie na żywo” można modyfikować za pomocą obiektu ImageCapture: ImageCapture.getPhotoCapabilities() zwraca obiekt PhotoCapabilities, który zapewnia dostęp do funkcji kamery „Nie na żywo”. Od wersji 61 Chrome ImageCapture.getPhotoSettings()zwraca obiekt PhotoSettingsz konkretnymi bieżącymi ustawieniami. Do tej sekcji należą na przykład rozdzielczość zdjęć, redukcja efektu czerwonych oczu i tryb lampy błyskowej (z wyjątkiem trybu latarki):

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 „Na żywo” kamery można konfigurować w podglądzie MediaStreamTrackapplyConstraints() ograniczeń, 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 „Nie na żywo” są konfigurowane za pomocą opcjonalnego słownika takePhoto() PhotoSettings, 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óżnice w wymiarach między wynikami grabFrame()takePhoto().

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

grabFrame() pobiera tylko następny dostępny VideoFrameMediaStreamTrack w ramach procesu renderowania, podczas gdy takePhoto() przerywa MediaStream, ponownie konfiguruje aparat, robi zdjęcie (zwykle w skompresowanym formacie, stąd Blob), a potem wznawia MediaStreamTrack. Oznacza to, że takePhoto() zapewnia dostęp do wszystkich możliwości aparatu w zakresie rozdzielczości zdjęć. Wcześniej można było „robić zdjęcia” tylko przez wywołanie funkcji drawImage() w elemencie canvas, używając jako źródła filmu (jak w tym przykładzie tutaj).

Więcej informacji znajdziesz w sekcji README.md.

W tym pokazie wymiary <canvas> są ustawione na rozdzielczość strumienia wideo, a naturalny rozmiar <img> to maksymalna rozdzielczość zdjęć zrobionych aparatem. Do ustawienia rozmiaru wyświetlania obu elementów służy oczywiście CSS.

Pełen zakres dostępnych rozdzielczości aparatu dla zdjęć można uzyskać i ustawić, używając wartości MediaSettingsRange dla PhotoCapabilities.imageHeightimageWidth. Pamiętaj, że minimalne i maksymalne ograniczenia szerokości i wysokości w przypadku getUserMedia() dotyczą filmów, które (jak już wspomnieliśmy) mogą się różnić od możliwości aparatu w przypadku zdjęć. Inaczej mówiąc, podczas zapisywania z poziomu getUserMedia() na kanwie możesz nie mieć dostępu do pełnej rozdzielczości urządzenia. Demo ograniczeń rozdzielczości w WebRTC pokazuje, jak ustawić ograniczenia getUserMedia() dla rozdzielczości.

Coś jeszcze?

  • Interfejs Shape Detection API dobrze współpracuje z Capture Image: grabFrame() może być wywoływany wielokrotnie, aby przesyłać ImageBitmaps do FaceDetector lub BarcodeDetector. Więcej informacji o interfejsie API znajdziesz w poście na blogu Paula Kinlana.

  • Lampę błyskową (lampkę urządzenia) można włączyć, klikając FillLightMode w sekcji PhotoCapabilities, ale tryb latarki (lampka błyskowa stale włączona) można znaleźć w sekcji MediaTrackCapabilities.

Demonstracje i przykłady kodu

Pomoc

  • Chrome 59 na Androidzie i komputerach.
  • Chrome Canary na Androidzie i komputerach w wersji starszej niż 59 z włączonymi funkcjami eksperymentalnej platformy internetowej.

Więcej informacji