Chụp ảnh và kiểm soát chế độ cài đặt của máy ảnh

Image Capture là một API để chụp ảnh tĩnh và định cấu hình các chế độ cài đặt phần cứng của máy ảnh. API này có trong Chrome 59 trên Android và máy tính. Chúng tôi cũng đã phát hành thư viện polyfill của ImageCapture.

API này cho phép kiểm soát các tính năng của máy ảnh như thu phóng, độ sáng, độ tương phản, ISO và cân bằng trắng. Hơn hết, Chụp ảnh cho phép bạn sử dụng các tính năng có độ phân giải đầy đủ của mọi máy ảnh hoặc webcam của thiết bị hiện có. Các kỹ thuật chụp ảnh trước đây trên web đã sử dụng ảnh chụp nhanh video, độ phân giải thấp hơn so với ảnh tĩnh.

Đối tượng ImageCapture được tạo với MediaStreamTrack làm nguồn. Sau đó, API có 2 phương thức ghi lại takePhoto()grabFrame(), cũng như cách truy xuất các tính năng và chế độ cài đặt của máy ảnh, cũng như thay đổi các chế độ cài đặt đó.

Công trường

API Chụp ảnh có quyền truy cập vào máy ảnh thông qua MediaStreamTrack lấy từ getUserMedia():

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

Bạn có thể dùng thử mã này trong bảng điều khiển Công cụ cho nhà phát triển.

Quay hình

Có hai cách chụp: toàn khung hình và chụp nhanh. takePhoto() trả về một Blob, kết quả của một lần phơi sáng ảnh. Bạn có thể tải xuống, lưu trữ dữ liệu này trong trình duyệt hoặc hiển thị trong phần tử <img>. Phương pháp này sử dụng độ phân giải cao nhất hiện có của máy ảnh. Ví dụ:

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() trả về một đối tượng ImageBitmap, một ảnh chụp nhanh của video trực tiếp, có thể (chẳng hạn) được vẽ trên <canvas> rồi sau đó được xử lý sau để thay đổi các giá trị màu một cách có chọn lọc. Lưu ý rằng ImageBitmap sẽ chỉ có độ phân giải của nguồn video – thường thấp hơn khả năng chụp ảnh tĩnh của máy ảnh. Ví dụ:

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

Chức năng và chế độ cài đặt

Có một số cách để thao tác với chế độ cài đặt chụp, tuỳ thuộc vào việc thay đổi sẽ được phản ánh trong MediaStreamTrack hay chỉ có thể được nhìn thấy sau takePhoto(). Ví dụ: sự thay đổi về cấp độ zoom được truyền ngay lập tức sang MediaStreamTrack, trong khi tính năng giảm mắt đỏ (nếu được đặt) chỉ áp dụng khi ảnh đang được chụp.

Chế độ cài đặt và chức năng của camera "trực tiếp" được điều chỉnh thông qua bản xem trước MediaStreamTrack: MediaStreamTrack.getCapabilities() trả về từ điển MediaTrackCapabilities có các khả năng được hỗ trợ cụ thể và phạm vi hoặc giá trị được phép, ví dụ: phạm vi thu phóng được hỗ trợ hoặc chế độ cân bằng trắng được phép. Tương ứng, MediaStreamTrack.getSettings() sẽ trả về một MediaTrackSettings với các chế độ cài đặt cụ thể hiện tại. Chế độ thu phóng, độ sáng và đèn pin thuộc danh mục này, ví dụ:

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

Chế độ cài đặt và chức năng của camera "Không phát trực tiếp" được thao tác thông qua đối tượng ImageCapture: ImageCapture.getPhotoCapabilities() trả về một đối tượng PhotoCapabilities cung cấp quyền truy cập vào các tính năng hiện có của camera là "Không phát trực tiếp". Tương ứng, kể từ Chrome 61, ImageCapture.getPhotoSettings() sẽ trả về đối tượng PhotoSettings với chế độ cài đặt cụ thể hiện tại. Độ phân giải ảnh, giảm mắt đỏ và chế độ flash (ngoại trừ đèn pin) thuộc về mục này, ví dụ:

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

Đang định cấu hình

Bạn có thể định cấu hình chế độ cài đặt camera "Trực tiếp" thông qua các quy tắc ràng buộc applyConstraints() của bản xem trước MediaStreamTrack, ví dụ:

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

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

Các chế độ cài đặt camera "Không phát trực tiếp" được định cấu hình bằng từ điển PhotoSettings không bắt buộc của takePhoto(), ví dụ:

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

Chức năng của máy ảnh

Nếu chạy mã ở trên, bạn sẽ nhận thấy sự khác biệt về kích thước giữa kết quả grabFrame()takePhoto().

Phương thức takePhoto() cho phép truy cập vào độ phân giải tối đa của máy ảnh.

grabFrame() chỉ lấy VideoFrame có sẵn tiếp theo ở MediaStreamTrack bên trong quy trình kết xuất, trong khi takePhoto() làm gián đoạn MediaStream, định cấu hình lại máy ảnh, chụp ảnh (thường ở định dạng nén, sau đó là Blob) rồi tiếp tục MediaStreamTrack. Về cơ bản, điều này có nghĩa là takePhoto() cho phép sử dụng toàn bộ khả năng phân giải hình ảnh tĩnh của máy ảnh. Trước đây, bạn chỉ có thể "chụp ảnh" bằng cách gọi drawImage() trên phần tử canvas, sử dụng một video làm nguồn (theo ví dụ tại đây).

Bạn có thể tìm thêm thông tin trong phần README.md.

Trong bản minh hoạ này, kích thước <canvas> được đặt thành độ phân giải của luồng video, trong khi kích thước tự nhiên của <img> là độ phân giải hình ảnh tĩnh tối đa của máy ảnh. Tất nhiên, CSS được dùng để đặt kích thước hiển thị cho cả hai.

Bạn có thể lấy và đặt toàn bộ độ phân giải máy ảnh hiện có cho ảnh tĩnh bằng cách sử dụng các giá trị MediaSettingsRange cho PhotoCapabilities.imageHeightimageWidth. Xin lưu ý rằng các điều kiện ràng buộc về chiều rộng và chiều cao tối thiểu và tối đa cho getUserMedia() là dành cho video, (như đã thảo luận) có thể khác với các tính năng của camera đối với ảnh tĩnh. Nói cách khác, bạn có thể không truy cập được vào khả năng phân giải đầy đủ của thiết bị khi lưu từ getUserMedia() vào canvas. Bản minh hoạ về quy tắc ràng buộc đối với độ phân giải của WebRTC cho thấy cách đặt các quy tắc ràng buộc getUserMedia() đối với độ phân giải.

Còn thiết lập gì nữa không?

  • API Phát hiện hình dạng hoạt động tốt với Chụp ảnh: grabFrame() có thể được gọi nhiều lần để cấp dữ liệu ImageBitmap cho FaceDetector hoặc BarcodeDetector. Hãy tìm hiểu thêm về API trong bài đăng trên blog của Paul Kinlan.

  • Bạn có thể dùng Đèn flash của máy ảnh (ánh sáng của thiết bị) thông qua FillLightMode trong PhotoCapabilities , nhưng bạn có thể tìm thấy Chế độ đèn pin (bật đèn flash liên tục) trong MediaTrackCapabilities.

Bản minh hoạ và mã mẫu

Hỗ trợ

  • Chrome 59 trên Android và máy tính.
  • Chrome Canary trên Android và máy tính trước phiên bản 59 đã bật các tính năng của Nền tảng web thử nghiệm.

Tìm hiểu thêm