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

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

Resim Yakalama, fotoğraf çekmek ve kamera donanım ayarlarını yapılandırmak için kullanılan bir API'dir. Bu API, Android ve masaüstünde Chrome 59'da kullanılabilir. Ayrıca bir ImageCapture polyfill kitaplığı da yayınladık.

API; yakınlaştırma, parlaklık, kontrast, ISO ve beyaz dengesi gibi kamera özellikleri üzerinde kontrol sağlar. En iyisi de Resim Yakalama, mevcut tüm cihaz kameralarının veya web kameralarının tam çözünürlük özelliklerine erişmenize olanak tanır. Web'de fotoğraf çekmek için daha önce kullanılan tekniklerde, video anlık görüntüleri kullanılıyordu. Bu görüntüler, hareketsiz görüntülere kıyasla daha düşük çözünürlükteydi.

ImageCapture nesnesi, kaynak olarak MediaStreamTrack ile oluşturulur. API'de iki yakalama yöntemi (takePhoto() ve grabFrame()) ve 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şir:

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 DevTools konsolundan deneyebilirsiniz.

Fotoğraf çek

Fotoğraf çekme işlemi iki şekilde yapılabilir: tam çerçeve ve hızlı anlık görüntü. takePhoto(), tek bir fotoğrafik pozlamanın sonucu olan Blob değerini döndürür. Bu değer indirilebilir, tarayıcı tarafından depolanabilir veya bir <img> öğesinde görüntülenebilir. Bu yöntem, mevcut en yüksek fotoğraf kamerası çözünürlüğünü kullanı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ünü döndüren bir ImageBitmap nesnesi döndürür. Bu görüntü, örneğin bir <canvas> üzerine çizilebilir ve ardından renk değerlerini seçerek değiştirmek için son işleme tabi tutulabilir. ImageBitmap değerinin yalnızca video kaynağının çözünürlüğüne sahip olacağını unutmayın. Bu çözünürlük genellikle kameranın fotoğraf çekme ö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

Değişikliklerin MediaStreamTrack'e yansıtılıp yansıtılmayacağına veya yalnızca takePhoto()'ten sonra görülebilmesine bağlı olarak, yakalama ayarlarını değiştirmenin birkaç yolu vardır. Örneğin, zoom seviyesindeki bir değişiklik hemen MediaStreamTrack'e iletilir. Kırmızı göz azaltma ayarı ise yalnızca fotoğraf çekilirken uygulanır.

"Canlı" kamera özellikleri ve ayarları önizleme aracılığıyla değiştirilir MediaStreamTrack: MediaStreamTrack.getCapabilities(), desteklenen belirli özellikleri ve aralıkları ya da izin verilen değerleri (ör. desteklenen yakınlaştırma aralığı veya izin verilen beyaz denge modları) içeren bir MediaTrackCapabilities sözlük döndürür. Buna karşılık MediaStreamTrack.getSettings(), geçerli ayarları içeren bir MediaTrackSettings döndürür. Yakınlaştırma, parlaklık ve el feneri 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(), geçerli ayarları içeren bir PhotoSettings nesnesi döndürür. Fotoğraf çözünürlüğü, kırmızı göz azaltma ve flaş modu (el feneri hariç) bu bölüme aittir. Ö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'nin 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()'nin 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 bir fark olduğunu fark edersiniz.

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

grabFrame(), oluşturucu işleminin içindeki MediaStreamTrack'de kullanılabilir bir sonraki VideoFrame'yi alır. takePhoto() ise MediaStream'yi kesintiye uğratır, kamerayı yeniden yapılandırır, fotoğrafı çeker (genellikle sıkıştırılmış biçimde, bu nedenle Blob) ve ardından MediaStreamTrack'yi devam ettirir. Özetle bu, takePhoto()'ün kameranın tüm fotoğraf çözünürlüğü özelliklerine erişim sağladığı anlamına gelir. Daha önce, yalnızca bir canvas öğesinde drawImage() çağrılarak kaynak olarak video kullanılarak "fotoğraf çekme" işlemi yapılabiliyordu (Buradaki örnekte gösterildiği gibi).

Daha fazla bilgiyi README.md bölümünde bulabilirsiniz.

Bu demoda <canvas> boyutları, video akışının çözünürlüğüne ayarlanmıştır. <img>'un doğal boyutu ise kameranın maksimum fotoğraf çözünürlüğüdür. Elbette CSS, her ikisinin de ekran boyutunu ayarlamak için kullanılır.

Hareketsiz görüntüler 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 olduğunu ve (konuşulduğu gibi) hareketsiz görüntüler için kamera özelliklerinden farklı olabileceğini unutmayın. Diğer bir deyişle, getUserMedia()'ten kanvasa kaydederken cihazınızın tam çözünürlük özelliklerine erişemeyebilirsiniz. WebRTC çözünürlük kısıtlaması demosunda, çözünürlük için getUserMedia() kısıtlamalarının nasıl ayarlanacağı gösterilmektedir.

Başka bir şey var mıydı?

  • Shape Detection API, görüntü yakalama ile iyi çalışır: grabFrame(), ImageBitmap'leri bir FaceDetector veya BarcodeDetector'e beslemek için tekrar tekrar çağrılabilir. Paul Kinlan'ın blog yayınını inceleyerek API hakkında daha fazla bilgi edinebilirsiniz.

  • Kamera flaşı'na (cihaz ışığı) PhotoCapabilities bölümündeki FillLightMode simgesinden erişilebilir. El feneri modu'na (flaş sürekli açık) ise MediaTrackCapabilities bölümünden erişilebilir.

Demolar ve kod örnekleri

Destek

  • Android ve masaüstünde Chrome 59.
  • Deneysel Web Platformu özelliklerinin etkin olduğu Android ve masaüstünde 59'dan önceki Chrome Canary sürümleri.

Daha fazla bilgi