Mengambil foto dan mengontrol setelan kamera

Pengambilan Gambar adalah API untuk mengambil gambar diam dan mengonfigurasi hardware kamera setelan. API ini tersedia di Chrome 59 untuk Android dan desktop. Kami juga sudah memublikasikan library polyfill ImageCapture.

API ini memungkinkan kontrol atas fitur kamera seperti zoom, kecerahan, kontras, ISO, dan keseimbangan putih. Yang terbaik dari semuanya, Pengambilan Gambar memungkinkan Anda mengakses kemampuan resolusi penuh dari kamera atau {i>webcam<i} perangkat yang tersedia. Teknik sebelumnya mengambil foto di Web telah menggunakan snapshot video, yang memiliki resolusi lebih rendah dari yang tersedia untuk gambar diam.

Objek ImageCapture dibuat dengan MediaStreamTrack sebagai sumber. Tujuan API kemudian memiliki dua metode pengambilan takePhoto() dan grabFrame(), serta cara untuk mengambil kemampuan dan setelan kamera, dan untuk mengubahnya setelan.

Konstruksi

Image Capture API mendapatkan akses ke kamera melalui MediaStreamTrack yang diperoleh dari 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);
}

Anda dapat mencoba kode ini dari konsol DevTools.

Rekam

Pengambilan gambar dapat dilakukan dengan dua cara: frame penuh dan snapshot cepat. takePhoto() menampilkan Blob, hasil dari eksposur fotografi tunggal, yang dapat didownload, disimpan oleh browser, atau ditampilkan di <img> . Metode ini menggunakan resolusi kamera fotografi tertinggi yang tersedia. Contoh:

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() menampilkan objek ImageBitmap, ringkasan video live, yang (misalnya) dapat digambar di <canvas> dan kemudian diproses kembali untuk mengubah nilai warna secara selektif. Perlu diketahui bahwa ImageBitmap hanya akan memiliki resolusi sumber video — yang biasanya akan lebih rendah dari resolusi kamera kemampuan gambar diam. Contoh:

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

Kemampuan dan setelan

Ada sejumlah cara untuk memanipulasi setelan tangkapan, tergantung pada apakah perubahan akan tercermin dalam MediaStreamTrack atau hanya dapat ditunjukkan terlihat setelah takePhoto(). Misalnya, perubahan level zoom secara langsung disebarluaskan ke MediaStreamTrack sedangkan reduksi mata merah, bila ditetapkan, hanya diterapkan bila foto sedang diambil.

"Langsung" kemampuan dan setelan kamera dimanipulasi melalui pratinjau MediaStreamTrack: MediaStreamTrack.getCapabilities() menampilkan MediaTrackCapabilities dengan kemampuan konkret yang didukung dan rentang atau yang diizinkan yang berbeda, mis. mendukung rentang zoom atau mode white balance yang diizinkan. Dengan demikian, MediaStreamTrack.getSettings() menampilkan MediaTrackSettings dengan pengaturan saat ini yang konkret. Mode zoom, kecerahan, dan senter termasuk dalam kategori ini, misalnya:

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

"Tidak Aktif" kemampuan dan setelan kamera dimanipulasi melalui Objek ImageCapture: ImageCapture.getPhotoCapabilities() menampilkan PhotoCapabilities yang memberikan akses ke "Non-Live" kapabilitas kamera yang tersedia. Oleh karena itu, mulai Chrome 61, ImageCapture.getPhotoSettings() mengembalikan PhotoSettings dengan pengaturan saat ini yang konkret. Resolusi foto, mata merah mode pengurangan dan flash (kecuali flash) termasuk dalam bagian ini, misalnya:

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

Mengonfigurasi

"Langsung" setelan kamera dapat dikonfigurasi melalui pratinjau applyConstraints() milik MediaStreamTrack batasan , misalnya:

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

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

"Tidak Aktif" setelan kamera dikonfigurasi dengan atribut takePhoto() PhotoSettings kamus, misalnya:

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

Kemampuan kamera

Jika Anda menjalankan kode di atas, Anda akan melihat perbedaan dimensi antara grabFrame() dan takePhoto() hasil.

Metode takePhoto() memberikan akses ke resolusi maksimum kamera.

grabFrame() baru saja mengambil VideoFrame berikutnya yang tersedia di MediaStreamTrack di dalam proses perender, sedangkan takePhoto() menyela MediaStream, mengkonfigurasi ulang kamera, mengambil foto (biasanya dalam format terkompresi, maka Blob) lalu melanjutkan MediaStreamTrack. Pada intinya, ini berarti bahwa takePhoto() memberikan akses ke resolusi penuh gambar diam kemampuan kamera dengan lebih baik. Sebelumnya, 'mengambil foto' hanya dapat dilakukan dengan cara memanggil drawImage() pada elemen canvas, menggunakan video sebagai sumber (sesuai dengan contoh di sini).

Informasi selengkapnya dapat ditemukan di bagian README.md.

Dalam demo ini, dimensi <canvas> disetel ke resolusi video streaming, sedangkan ukuran alami <img> adalah gambar diam maksimum resolusi kamera. Tentu saja CSS digunakan untuk mengatur tampilan ukuran keduanya.

Berbagai resolusi kamera yang tersedia untuk gambar diam dapat diperoleh dan disetel menggunakan nilai MediaSettingsRange untuk PhotoCapabilities.imageHeight dan imageWidth. Perhatikan bahwa batasan lebar dan tinggi minimum dan maksimum untuk getUserMedia() adalah untuk video, yang (seperti yang telah dibahas) mungkin berbeda dari kemampuan kamera untuk gambar diam. Dengan kata lain, Anda mungkin tidak dapat mengakses kemampuan resolusi penuh perangkat Anda saat menyimpan dari getUserMedia() ke kanvas. Demo batasan resolusi WebRTC menunjukkan cara menetapkan batasan getUserMedia() untuk resolusi.

Ada lagi?

Demo dan contoh kode

Dukungan

  • Chrome 59 di Android dan desktop.
  • Chrome Canary di Android dan desktop versi sebelumnya ke versi 59 dengan Fitur Platform Web Eksperimental diaktifkan.

Cari tahu selengkapnya