Fotoğraf çekin ve kamera ayarlarını kontrol edin

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

Resim Yakalama, hareketsiz görüntüler yakalamak ve kamera donanım ayarlarını yapılandırmak için kullanılan bir API'dir. Bu API, Android ve masaüstündeki Chrome 59 sürümünde kullanılabilir. Ayrıca, ImageCapture polyfill kitaplığı da yayınladık.

API; yakınlaştırma, parlaklık, kontrast, ISO ve beyaz dengesi gibi kamera özellikleri üzerinde kontrol olanağı sağlar. En iyi yanı da, Resim Yakalama özelliği herhangi bir cihaz kamerasının veya web kamerasının tam çözünürlük özelliklerine erişmenizi sağlar. Web'de fotoğraf çekmek için daha önceki tekniklerde, hareketsiz resimler için kullanılabilenden daha düşük çözünürlüklü video anlık görüntüleri kullanılıyordu.

Kaynak olarak MediaStreamTrack ile bir ImageCapture nesnesi oluşturuldu. API'de, takePhoto() ve grabFrame() adlı iki yakalama yönteminin yanı sıra kameranın özelliklerini ve ayarlarını alma ve bu ayarları değiştirme yöntemleri bulunur.

Yol çalışması

Image Capture API, getUserMedia() kaynağından alınan bir MediaStreamTrack aracılığıyla kameraya erişim sağlar:

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

Bu kodu Geliştirici Araçları konsolunda deneyebilirsiniz.

Çekim Yapın

İki şekilde fotoğraf çekebilirsiniz: tam kare ve hızlı anlık görüntü. takePhoto(), indirilebilecek, tarayıcı tarafından depolanabilecek veya bir <img> öğesinde görüntülenebilecek tek bir fotoğraf pozlamasının sonucu olan bir Blob döndürür. Bu yöntemde, mevcut en yüksek fotoğraf makinesi çözünürlüğü kullanılır. Örneğin:

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(), canlı videonun anlık görüntüsü olan bir ImageBitmap nesnesi döndürür. Bu nesne (örneğin) bir <canvas> üzerine çizilebilir ve ardından renk değerlerini seçici bir şekilde değiştirmek için son işlemden geçirilebilir. ImageBitmap yalnızca video kaynağının çözünürlüğüne sahip olur. Bu çözünürlük genellikle kameranın hareketsiz görüntü özelliklerinden daha düşüktür. Örneğin:

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

Özellikler ve ayarlar

Yakalama ayarlarını değiştirmenin, değişikliklerin MediaStreamTrack içinde yansıtılacağına veya yalnızca takePhoto() sonrasında görülebileceğine bağlı olarak çeşitli yolları vardır. Örneğin, zoom seviyesindeki bir değişiklik MediaStreamTrack değerine hemen uygulanır. Kırmızı göz azaltma özelliği ayarlandığında ise yalnızca fotoğraf çekilirken uygulanır.

"Canlı" kamera özellikleri ve ayarları önizleme aracılığıyla değiştirilir MediaStreamTrack: MediaStreamTrack.getCapabilities(), desteklenen somut özellikleri ve aralıkları ya da izin verilen değerleri (ör. desteklenen yakınlaştırma aralığı veya izin verilen beyaz dengesi modları) içeren bir MediaTrackCapabilities sözlük döndürür. Buna karşılık MediaStreamTrack.getSettings(), somut geçerli ayarlarla bir MediaTrackSettings döndürür. Yakınlaştırma, parlaklık ve flaş modu bu kategoriye aittir. Örneğin:

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

"Canlı Olmayan" kamera özellikleri ve ayarları, ImageCapture nesnesi aracılığıyla değiştirilir: ImageCapture.getPhotoCapabilities(), "Canlı Olmayan" kamera özelliklerine erişim sağlayan bir PhotoCapabilities nesnesi döndürür. Buna karşılık, Chrome 61'den itibaren ImageCapture.getPhotoSettings(), somut geçerli ayarlara sahip bir PhotoSettings nesnesi döndürür. Fotoğraf çözünürlüğü, kırmızı göz azaltma ve flaş modu (fener hariç) bu bölümde yer alır. Örneğin:

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

Yapılandırma

"Canlı" kamera ayarları, önizleme MediaStreamTrack applyConstraints() kısıtlamaları aracılığıyla yapılandırılabilir. Örneğin:

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

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

"Canlı Olmayan" kamera ayarları, takePhoto() ürününün isteğe bağlı PhotoSettings sözlüğüyle yapılandırılır. Örneğin:

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

Kamera özellikleri

Yukarıdaki kodu çalıştırırsanız grabFrame() ve takePhoto() sonuçları arasındaki boyutlarda fark görürsünüz.

takePhoto() yöntemi, kameranın maksimum çözünürlüğüne erişim sağlar.

grabFrame(), oluşturucu işleminin içinde MediaStreamTrack içinde kullanılabilen bir sonraki VideoFrame öğesini yalnızca alır, takePhoto() ise MediaStream öğesini kesintiye uğratır, kamerayı yeniden yapılandırır, fotoğrafı çeker (genellikle sıkıştırılmış biçimdedir; dolayısıyla Blob) ve ardından MediaStreamTrack işlemini devam ettirir. Esasen bu, takePhoto() ürününün, kameranın tüm sabit görüntü çözünürlüğü özelliklerine erişim sağladığı anlamına gelir. Daha önce "fotoğraf çekmek" yalnızca canvas öğesinde drawImage() çağırıp kaynak olarak videoyu kullanmak mümkündü (buradaki örneğe göre).

README.md bölümünde daha fazla bilgi bulabilirsiniz.

Bu demoda, <canvas> boyutları video akışının çözünürlüğüne ayarlanmıştır. <img> öğesinin doğal boyutu ise kameranın maksimum sabit görüntü çözünürlüğüdür. CSS elbette her ikisinin de görüntüleme boyutunu ayarlamak için kullanılır.

Hareketsiz resimler için kullanılabilen tüm kamera çözünürlükleri, PhotoCapabilities.imageHeight ve imageWidth için MediaSettingsRange değerleri kullanılarak alınabilir ve ayarlanabilir. getUserMedia() için minimum ve maksimum genişlik ve yükseklik kısıtlamalarının video için geçerli olduğunu ve bu kısıtlamaların (açıklandığı gibi), hareketsiz resimlerdeki kamera özelliklerinden farklı olabileceğini unutmayın. Başka bir deyişle, getUserMedia() uygulamasından bir kanvasa kaydederken cihazınızın tam çözünürlük özelliklerine erişemeyebilirsiniz. WebRTC çözüm kısıtlaması demosu, çözünürlük için getUserMedia() kısıtlamalarının nasıl ayarlanacağını gösterir.

Eklemek istediğiniz başka şey var mı?

  • Shape Detection API, Resim Yakalama ile uyumlu bir şekilde çalışır: grabFrame(), ImageBitmap öğelerini FaceDetector veya BarcodeDetector öğesine beslemek için tekrar tekrar çağrılabilir. API hakkında daha fazla bilgiyi Paul Kinlan'ın blog yayınında bulabilirsiniz.

  • Kamera flaşına (cihaz ışığı) PhotoCapabilities içindeki FillLightMode üzerinden erişilebilir ancak Flaş modu (sürekli açık) MediaTrackCapabilities bölümünde bulunabilir.

Demolar ve kod örnekleri

Destek

  • Android ve masaüstünde Chrome 59.
  • Deneysel Web Platformu özelliklerinin etkin olduğu, Android ve masaüstü 59 sürümünden önceki Chrome Canary sürümü.

Daha fazla bilgi