Maak foto's en bedien de camera-instellingen

Image Capture is een API om stilstaande beelden vast te leggen en de hardware-instellingen van de camera te configureren. Deze API is beschikbaar in Chrome 59 op Android en desktop. We hebben ook een ImageCapture polyfill-bibliotheek gepubliceerd.

De API maakt controle mogelijk over camerafuncties zoals zoom, helderheid, contrast, ISO en witbalans. Het beste van alles is dat u met Image Capture toegang krijgt tot de volledige resolutiemogelijkheden van elke beschikbare apparaatcamera of webcam. Bij eerdere technieken voor het maken van foto's op internet werd gebruik gemaakt van videosnapshots, die een lagere resolutie hebben dan de resolutie die beschikbaar is voor stilstaande beelden.

Een ImageCapture object wordt geconstrueerd met een MediaStreamTrack als bron. De API heeft dan twee opnamemethoden takePhoto() en grabFrame() en manieren om de mogelijkheden en instellingen van de camera op te halen en deze instellingen te wijzigen.

Bouw

De Image Capture API krijgt toegang tot een camera via een MediaStreamTrack verkregen van 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);
}

U kunt deze code uitproberen via de DevTools-console.

Vastlegging

Vastleggen kan op twee manieren: full frame en quick snapshot. takePhoto() retourneert een Blob , het resultaat van een enkele fotografische belichting , die kan worden gedownload, opgeslagen door de browser of weergegeven in een <img> -element. Deze methode maakt gebruik van de hoogst beschikbare fotocameraresolutie. Bijvoorbeeld:

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() retourneert een ImageBitmap object, een momentopname van live video , die (bijvoorbeeld) op een <canvas > kan worden getekend en vervolgens kan worden nabewerkt om selectief de kleurwaarden te wijzigen. Houd er rekening mee dat de ImageBitmap alleen de resolutie van de videobron heeft, die doorgaans lager zal zijn dan de mogelijkheden voor stilstaande beelden van de camera. Bijvoorbeeld:

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

Mogelijkheden en instellingen

Er zijn een aantal manieren om de opname-instellingen te manipuleren, afhankelijk van of de wijzigingen worden weerspiegeld in MediaStreamTrack of alleen zichtbaar zijn na takePhoto() . Een verandering in zoom wordt bijvoorbeeld onmiddellijk doorgegeven aan de MediaStreamTrack terwijl de rode-ogenreductie, indien ingesteld, alleen wordt toegepast wanneer de foto wordt gemaakt.

"Live" cameramogelijkheden en -instellingen worden gemanipuleerd via de preview MediaStreamTrack : MediaStreamTrack.getCapabilities() retourneert een MediaTrackCapabilities -woordenboek met de concrete ondersteunde mogelijkheden en de bereiken of toegestane waarden, bijvoorbeeld het ondersteunde zoombereik of de toegestane witbalansmodi. Dienovereenkomstig retourneert MediaStreamTrack.getSettings() een MediaTrackSettings met de concrete huidige instellingen. Zoom, helderheid en zaklampmodus behoren bijvoorbeeld tot deze categorie:

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

"Niet-Live" cameramogelijkheden en -instellingen worden gemanipuleerd via het ImageCapture object: ImageCapture.getPhotoCapabilities() retourneert een PhotoCapabilities object dat toegang biedt tot "Niet-Live" beschikbare cameramogelijkheden. Op overeenkomstige wijze retourneert ImageCapture.getPhotoSettings() vanaf Chrome 61 een PhotoSettings object met de concrete huidige instellingen. De fotoresolutie, rode-ogenreductie en flitsmodus (behalve zaklamp) behoren bijvoorbeeld tot deze sectie:

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

Configureren

"Live" camera-instellingen kunnen worden geconfigureerd via de applyConstraints() -beperkingen van de preview MediaStreamTrack , bijvoorbeeld:

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

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

"Niet-Live" camera-instellingen worden geconfigureerd met het optionele PhotoSettings woordenboek van takePhoto() , bijvoorbeeld:

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

Cameramogelijkheden

Als u de bovenstaande code uitvoert, zult u een verschil in afmetingen opmerken tussen de resultaten grabFrame() en takePhoto() .

De takePhoto() methode geeft toegang tot de maximale resolutie van de camera.

grabFrame() neemt gewoon het volgende beschikbare VideoFrame in de MediaStreamTrack binnen het rendererproces, terwijl takePhoto() de MediaStream onderbreekt, de camera opnieuw configureert, de foto maakt (meestal in een gecomprimeerd formaat, vandaar de Blob ) en vervolgens de MediaStreamTrack hervat. In wezen betekent dit dat takePhoto() toegang geeft tot de volledige resolutiemogelijkheden voor stilstaande beelden van de camera. Voorheen was het alleen mogelijk om 'een foto te maken' door drawImage() aan te roepen op een canvas , met een video als bron (zoals in het voorbeeld hier ).

Meer informatie vindt u in de README.md- sectie .

In deze demo zijn de <canvas> -afmetingen ingesteld op de resolutie van de videostream, terwijl de natuurlijke grootte van de <img> de maximale resolutie van stilstaande beelden van de camera is. CSS wordt uiteraard gebruikt om de weergavegrootte van beide in te stellen.

Het volledige bereik aan beschikbare cameraresoluties voor stilstaande beelden kan worden opgehaald en ingesteld met behulp van de MediaSettingsRange waarden voor PhotoCapabilities.imageHeight en imageWidth . Merk op dat de minimale en maximale breedte- en hoogtebeperkingen voor getUserMedia() gelden voor video, die (zoals besproken) kan verschillen van de cameramogelijkheden voor stilstaande beelden. Met andere woorden: u heeft mogelijk geen toegang tot de volledige resolutiemogelijkheden van uw apparaat wanneer u vanuit getUserMedia() opslaat op een canvas. De demo van WebRTC-resolutiebeperking laat zien hoe u getUserMedia() -beperkingen voor resolutie instelt.

Nog iets anders?

Demo's en codevoorbeelden

Steun

  • Chrome 59 op Android en desktop.
  • Chrome Canary op Android en desktop vóór 59 met Experimental Web Platform -functies ingeschakeld.

Meer informatie