写真の撮影とカメラ設定の制御

Image Capture は、静止画像をキャプチャし、カメラのハードウェア設定を構成するための API です。この API は Android 版とパソコン版 Chrome 59 で利用できます。ImageCapture ポリフィル ライブラリも公開しています。

この API を使用すると、ズーム、明るさ、コントラスト、ISO、ホワイト バランスなどのカメラ機能を制御できます。最大のメリットは、Image Capture を使用すると、デバイスのカメラやウェブカメラの最大解像度の機能にアクセスできます。ウェブで写真を撮影する以前の技術では、静止画像よりも解像度が低い動画スナップショットが使用されていました。

ImageCapture オブジェクトは、MediaStreamTrack をソースとして構築されます。この API には、takePhoto()grabFrame() の 2 つのキャプチャ メソッドがあり、カメラの機能と設定を取得する方法、それらの設定を変更する方法があります。

工事

Image Capture API は、getUserMedia() から取得した MediaStreamTrack を介してカメラにアクセスします。

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

このコードは DevTools コンソールから試すことができます。

撮影

キャプチャには、フルフレームとクイック スナップショットの 2 つの方法があります。takePhoto() は、写真の 1 回の露出の結果である Blob を返します。これはダウンロード、ブラウザで保存、または <img> 要素で表示できます。この方法では、写真カメラの最高解像度を使用します。次に例を示します。

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()ImageBitmap オブジェクト(ライブ動画のスナップショット)を返します。このオブジェクトは、たとえば <canvas> に描画され、後処理されて色の値を選択的に変更できます。ImageBitmap は動画ソースの解像度のみを持ちます。これは通常、カメラの静止画機能よりも低くなります。次に例を示します。

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

機能と設定

キャプチャ設定を操作するには、変更が MediaStreamTrack に反映されるか、takePhoto() の後にのみ表示できるかに応じて、いくつかの方法があります。たとえば、zoom レベルの変更はすぐに MediaStreamTrack に反映されますが、赤目補正が設定されている場合は、写真の撮影時にのみ適用されます。

「ライブ」カメラの機能と設定は、プレビュー MediaStreamTrack を介して操作します。MediaStreamTrack.getCapabilities() は、サポートされている具体的な機能と範囲または許容値(サポートされているズーム範囲や許可されるホワイト バランス モードなど)を含む MediaTrackCapabilities 辞書を返します。それに応じて、MediaStreamTrack.getSettings() は具体的な現在の設定を含む MediaTrackSettings を返します。ズーム、明るさ、トーチモードはこのカテゴリに属します。次に例を示します。

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

「非ライブ」カメラ機能と設定は、ImageCapture オブジェクトを介して操作します。ImageCapture.getPhotoCapabilities() は、「非ライブ」カメラ機能へのアクセスを提供する PhotoCapabilities オブジェクトを返します。これに対応して、Chrome 61 以降では、ImageCapture.getPhotoSettings() は具体的な現在の設定を含む PhotoSettings オブジェクトを返します。写真の解像度、赤目補正、フラッシュ モード(トーチを除く)はこのセクションに属します。次に例を示します。

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

構成

「ライブ」カメラ設定は、プレビュー MediaStreamTrackapplyConstraints() 制約を介して構成できます。次に例を示します。

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

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

「非ライブ」カメラの設定は、takePhoto() のオプションである PhotoSettings 辞書を使用して構成します。次に例を示します。

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

カメラ機能

上記のコードを実行すると、grabFrame()takePhoto() の結果のディメンションに違いがあることがわかります。

takePhoto() メソッドは、カメラの最大解像度へのアクセスを提供します。

grabFrame() は、レンダラ プロセス内の MediaStreamTrack で次の使用可能な VideoFrame を取得しますが、takePhoto()MediaStream を中断してカメラを再構成し、写真を(通常は圧縮形式、つまり Blob で)撮影し、MediaStreamTrack を再開します。要するに、takePhoto() はカメラの完全な静止画解像度の機能にアクセスできることを意味します。以前は、動画をソースとして使用し、canvas 要素で drawImage() を呼び出して「写真を撮る」ことしかできませんでした(こちらの例を参照)。

詳しくは、README.md のセクションをご覧ください。

このデモでは、<canvas> ディメンションは動画ストリームの解像度に設定されますが、<img> の自然なサイズは、カメラの静止画像の最大解像度です。両方の表示サイズを設定するために CSS を使用します

静止画像で使用可能なすべてのカメラ解像度を取得、設定するには、PhotoCapabilities.imageHeightimageWidthMediaSettingsRange 値を使用します。なお、getUserMedia() の幅と高さの最小値と最大値は動画に対する制約であり、前述のとおり、静止画像のカメラ機能とは異なる場合があります。つまり、getUserMedia() からキャンバスに保存する際に、デバイスの最大解像度の機能にアクセスできないことがあります。WebRTC の解決制約のデモでは、解決用の getUserMedia() 制約を設定する方法を示します。

さらに設定を続けますか?

  • Shape Detection API は、画像キャプチャで適切に機能します。grabFrame() を繰り返し呼び出して、ImageBitmapFaceDetector または BarcodeDetector にフィードできます。API の詳細については、Paul Kinlan のブログ投稿をご覧ください。

  • カメラのフラッシュ(デバイスのライト)は PhotoCapabilitiesFillLightMode からアクセスできますが、懐中電灯モード(フラッシュ常時オン)は MediaTrackCapabilities にあります。

デモとコードサンプル

サポート

  • Android およびパソコン版 Chrome 59
  • 試験運用版ウェブ プラットフォームの機能が有効になっている、Android と 59 より前のパソコン上の Chrome Canary。

補足説明