이미지 캡처는 스틸 이미지를 캡처하고 카메라 하드웨어 설정을 구성하는 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
를 반환하며 이는 브라우저에서 다운로드하거나 저장하거나 <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()
는 <canvas
>에 그린 다음 후처리하여 색상 값을 선택적으로 변경할 수 있는 라이브 동영상의 스냅샷인 ImageBitmap
객체를 반환합니다. 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는 이미지 캡처에서 잘 작동합니다.
grabFrame()
를 반복적으로 호출하여ImageBitmap
를FaceDetector
또는BarcodeDetector
에 제공할 수 있습니다. API에 관한 자세한 내용은 폴 킨란의 블로그 게시물을 참고하세요.카메라 플래시 (기기 조명)는
PhotoCapabilities
의FillLightMode
를 통해 액세스할 수 있지만 토치 모드 (계속 플래시 켜짐)는MediaTrackCapabilities
에서 찾을 수 있습니다.
데모 및 코드 샘플
지원
- Android 및 데스크톱에서 실행되는 Chrome 59
- 실험용 웹 플랫폼 기능이 사용 설정된 59 이전 버전의 Android 및 데스크톱에서 실행되는 Chrome Canary