ถ่ายรูปและควบคุมการตั้งค่ากล้อง

การจับภาพเป็น API สำหรับถ่ายภาพนิ่งและกำหนดค่าฮาร์ดแวร์กล้อง API นี้มีให้บริการใน Chrome 59 ใน Android และเดสก์ท็อป นอกจากนี้ เรายังได้เผยแพร่ไลบรารี polyfill ของ ImageCapture ด้วย

API ช่วยให้ควบคุมฟีเจอร์ต่างๆ ของกล้อง เช่น การซูม, ความสว่าง, คอนทราสต์, ISO และไวท์บาลานซ์ได้ และเหนือสิ่งอื่นใด การจับภาพยังช่วยให้คุณ เข้าถึงความสามารถแบบเต็มความละเอียดของกล้องหรือเว็บแคมที่มีอยู่ได้ เทคนิคก่อนหน้านี้ในการถ่ายรูปบนเว็บได้ใช้สแนปชอตวิดีโอ ซึ่งมีความละเอียดต่ำกว่าสำหรับภาพนิ่ง

ออบเจ็กต์ ImageCapture สร้างขึ้นโดยมี MediaStreamTrack เป็นแหล่งที่มา จากนั้น API จะมีวิธีการจับภาพ 2 วิธี ได้แก่ takePhoto() และ grabFrame() และวิธีดึงข้อมูลความสามารถและการตั้งค่าของกล้อง รวมถึงเปลี่ยนการตั้งค่าเหล่านั้น

การก่อสร้าง

Image Capture API มีสิทธิ์เข้าถึงกล้องผ่าน MediaStreamTrack ที่ได้รับจาก 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);
}

คุณสามารถลองใช้โค้ดนี้ได้จากคอนโซลเครื่องมือสำหรับนักพัฒนาเว็บ

จับภาพ

การจับภาพทำได้ 2 วิธี ได้แก่ การจับภาพแบบเต็มเฟรมและการจับภาพด่วน 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() จะแสดงผลออบเจ็กต์ 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));

กำลังกำหนดค่า

คุณกำหนดการตั้งค่ากล้อง "สด" ได้ผ่านข้อจำกัดapplyConstraints()ของ MediaStreamTrack ตัวอย่าง ตัวอย่างเช่น

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

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

การตั้งค่ากล้อง "ไม่ได้เผยแพร่" ได้รับการกำหนดค่าด้วยพจนานุกรมPhotoSettingsที่ไม่บังคับของ takePhoto() ดังตัวอย่างต่อไปนี้

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() จะใช้ VideoFrame ถัดไปใน MediaStreamTrack ภายในกระบวนการแสดงผล ในขณะที่ takePhoto() ขัดจังหวะ MediaStream กำหนดค่ากล้องใหม่ ถ่ายภาพ (โดยปกติอยู่ในรูปแบบที่บีบอัด ดังนั้น Blob) แล้วจึงกลับสู่ MediaStreamTrack โดยพื้นฐานแล้ว นี่หมายความว่า takePhoto() ให้สิทธิ์เข้าถึงความสามารถด้านความละเอียดของภาพนิ่งเต็มรูปแบบของกล้อง ก่อนหน้านี้ คุณจะ "ถ่ายรูป" ได้โดยเรียกใช้ drawImage() ในเอลิเมนต์ canvas โดยใช้วิดีโอเป็นต้นฉบับเท่านั้น (ตามตัวอย่างที่นี่)

สามารถดูข้อมูลเพิ่มเติมได้ในส่วน README.md

ในการสาธิตนี้ มิติข้อมูล <canvas> ได้รับการตั้งค่าเป็นความละเอียดของสตรีมวิดีโอ ในขณะที่ขนาดธรรมชาติของ <img> คือความละเอียดสูงสุดของภาพนิ่งของกล้อง แน่นอนว่า CSS จะใช้ในการตั้งค่า ขนาดการแสดงผลของทั้ง 2 แบบ

คุณดูและตั้งค่าความละเอียดของกล้องทั้งหมดที่ใช้ได้สำหรับภาพนิ่งได้โดยใช้ค่า MediaSettingsRange สำหรับ PhotoCapabilities.imageHeight และ imageWidth โปรดทราบว่าข้อจำกัดต่ำสุดและสูงสุดของความกว้างและความสูงสำหรับ getUserMedia() มีไว้สำหรับวิดีโอ ซึ่ง (ตามที่กล่าวไว้) อาจแตกต่างจากความสามารถของกล้องสำหรับภาพนิ่ง กล่าวคือ คุณอาจเข้าถึงความสามารถด้านความละเอียดเต็มของอุปกรณ์ไม่ได้เมื่อบันทึกจาก getUserMedia() ไปยัง Canvas การสาธิตข้อจำกัดการแก้ปัญหาของ WebRTC จะแสดงวิธีตั้งค่าข้อจำกัด getUserMedia() สำหรับการแก้ปัญหา

มีอะไรเพิ่มเติมอีกไหม

  • Shape Detection API ทำงานได้ดีกับการจับภาพ โดยอาจมีการเรียก grabFrame() ซ้ำๆ เพื่อส่ง ImageBitmaps ไปยัง FaceDetector หรือ BarcodeDetector ดูข้อมูลเพิ่มเติมเกี่ยวกับ API จากบล็อกโพสต์ของ Paul Kinlan

  • แฟลชกล้อง (ไฟอุปกรณ์) เข้าถึงได้ผ่าน FillLightMode ใน PhotoCapabilities แต่คุณดูโหมดไฟฉาย (เปิดแฟลชอยู่ตลอดเวลา) ได้ใน MediaTrackCapabilities

การสาธิตและตัวอย่างโค้ด

การสนับสนุน

  • Chrome 59 ใน Android และเดสก์ท็อป
  • Chrome Canary บน Android และเดสก์ท็อปก่อนหน้ารุ่น 59 ที่มีการเปิดใช้ฟีเจอร์แพลตฟอร์มเว็บรุ่นทดลอง

ดูข้อมูลเพิ่มเติม