التقاط الصور والتحكّم في إعدادات الكاميرا

‫Image Capture هي واجهة برمجة تطبيقات لالتقاط الصور الثابتة وضبط إعدادات كاميرا الأجهزة. تتوفّر واجهة برمجة التطبيقات هذه في الإصدار 59 من Chrome على أجهزة Android وأجهزة الكمبيوتر المكتبي. لقد صعدنا أيضًا مكتبة ImageCapture polyfill.

تتيح واجهة برمجة التطبيقات التحكّم في ميزات الكاميرا، مثل التكبير/التصغير والسطوع والتباين ودرجة ISO وموازنة اللون الأبيض. والأفضل من ذلك، تتيح لك ميزة "التقاط الصور" الاستفادة من إمكانات الدقة الكاملة لأي كاميرا أو كاميرا ويب متاحة على الجهاز. كانت الأساليب السابقة لالتقاط الصور على الويب تستخدِم لقطات فيديو، التي تكون دقتها أقل من تلك المتاحة للصور الثابتة.

يتم إنشاء عنصر ImageCapture باستخدام MediaStreamTrack كمصدر. تتضمّن واجهة برمجة التطبيقات بعد ذلك طريقتَي التقاط 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);
}

يمكنك تجربة هذا الرمز من وحدة تحكّم أدوات المطوّرين.

التقاط

يمكن التقاط الصور بطريقتَين: إطار كامل ولقطة سريعة. تُعرِض دالة 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 الذي يتيح الوصول إلى إمكانات الكاميرا "غير المباشرة" المتاحة. وبالمثل، بدءًا من الإصدار 61 من Chrome، يعرض العنصر 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));

يتم ضبط إعدادات الكاميرا "غير المباشرة" باستخدام القاموس الاختياري 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 بالطبع لضبط حجم عرض كل منهما.

يمكن الحصول على النطاق الكامل لدرجات دقة الكاميرا المتاحة للصور الثابتة وضبطها باستخدام قيم MediaSettingsRange لكل من PhotoCapabilities.imageHeight و imageWidth. يُرجى العِلم أنّ الحد الأدنى والحد الأقصى لحدود العرض والارتفاع في getUserMedia() مخصّصان للفيديو، وقد يختلفان (كما سبق ذكره) عن قدرات الكاميرا في ما يتعلّق بالصور الثابتة. بعبارة أخرى، قد لا تتمكّن من الاستفادة من إمكانات الدقة الكاملة لجهازك عند الحفظ من getUserMedia() إلى لوحة. يوضّح العرض التقديمي لقيود الدقة في WebRTC كيفية ضبط قيود getUserMedia() لدرجة الدقة.

هل هناك خطوات أخرى تريد تنفيذها؟

  • تعمل Shape Detection API بشكل جيد مع ميزة "التقاط الصور": يمكن استدعاء grabFrame() بشكل متكرر لإدخال ImageBitmap إلى FaceDetector أو BarcodeDetector. يمكنك الاطّلاع على مزيد من المعلومات حول واجهة برمجة التطبيقات في مشاركة المدونة التي نشرها "بول كينلان".

  • يمكن الوصول إلى وميض الكاميرا (ضوء الجهاز) من خلال FillLightMode في PhotoCapabilities ، ولكن يمكن العثور على وضع مصباح يدوي (وميض الفلاش باستمرار) في MediaTrackCapabilities.

الإصدارات التجريبية وعينات الرموز البرمجية

الدعم

  • الإصدار 59 من Chrome على أجهزة Android والكمبيوتر المكتبي
  • إصدار Chrome Canary على أجهزة Android وأجهزة الكمبيوتر المكتبي الأقدم من الإصدار 59 مع تفعيل ميزات النظام الأساسي التجريبي للويب

التعرف على المزيد