Image Capture는 스틸 이미지를 캡처하고 카메라 하드웨어 설정을 구성하는 API입니다. 이 API는 Android 및 데스크톱의 Chrome 59에서 사용할 수 있습니다. ImageCapture polyfill 라이브러리도 게시되었습니다.
이 API를 사용하면 확대/축소, 밝기, 대비, ISO, 화이트 밸런스와 같은 카메라 기능을 제어할 수 있습니다. 무엇보다도 이미지 캡처를 사용하면 사용 가능한 기기 카메라 또는 웹캠의 전체 해상도 기능에 액세스할 수 있습니다. 이전의 웹 사진 촬영 기법은 정지 이미지에 사용할 수 있는 해상도보다 낮은 동영상 스냅샷을 사용했습니다.
ImageCapture
객체는 MediaStreamTrack
를 소스로 사용하여 구성됩니다. 그러면 API에는 두 가지 캡처 메서드 takePhoto()
및 grabFrame()
와 카메라의 기능 및 설정을 가져오고 이러한 설정을 변경하는 방법이 있습니다.
공사
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 콘솔에서 이 코드를 사용해 볼 수 있습니다.
캡처
캡처는 전체 프레임과 빠른 스냅샷이라는 두 가지 방법으로 할 수 있습니다. takePhoto()
는 단일 사진 노출의 결과인 Blob
를 반환합니다. 이 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));
구성
'실시간' 카메라 설정은 미리보기 MediaStreamTrack
의 applyConstraints()
제약 조건을 통해 구성할 수 있습니다. 예를 들면 다음과 같습니다.
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.imageHeight
및 imageWidth
의 MediaSettingsRange
값을 사용하여 정지 이미지에 사용할 수 있는 모든 카메라 해상도를 가져오고 설정할 수 있습니다. getUserMedia()
의 최소 및 최대 너비와 높이 제약 조건은 동영상용이며, 앞서 설명한 대로 정적 이미지의 카메라 기능과 다를 수 있습니다. 즉, getUserMedia()
에서 캔버스로 저장할 때 기기의 전체 해상도 기능에 액세스하지 못할 수 있습니다. WebRTC 해상도 제약 조건 데모에서는 해상도에 getUserMedia()
제약 조건을 설정하는 방법을 보여줍니다.
기타 설정
Shape Detection API는 Image Capture와 잘 작동합니다.
grabFrame()
를 반복적으로 호출하여ImageBitmap
를FaceDetector
또는BarcodeDetector
에 제공할 수 있습니다. Paul Kinlan의 블로그 게시물에서 API에 대해 자세히 알아보세요.카메라 플래시 (기기 조명)는
PhotoCapabilities
의FillLightMode
를 통해 액세스할 수 있지만 토치 모드 (플래시가 계속 켜짐)는MediaTrackCapabilities
에서 찾을 수 있습니다.
데모 및 코드 샘플
지원
- Android 및 데스크톱의 Chrome 59
- 실험용 웹 플랫폼 기능이 사용 설정된 Android 및 데스크톱의 Chrome Canary(59 이전 버전)