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

การจับภาพเป็น 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 ที่ให้สิทธิ์เข้าถึง "Non-Live" ความสามารถของกล้อง ตามที่สอดคล้องกัน เริ่มตั้งแต่ 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));

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

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

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

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

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

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

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

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

การสนับสนุน

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

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