إنّ فك ترميز الصور لاستخدامها مع لوحة صورة شائع جدًا، سواء كان ذلك للسماح للمستخدمين بتخصيص صورة رمزية أو اقتصاص صورة أو تكبير صورة فقط. تكمن مشكلة فك ترميز الصور في أنّها قد تستهلك الكثير من وحدة المعالجة المركزية، ما قد يؤدي أحيانًا إلى حدوث تقطُّع أو ظهور تأثير لوحة الشطرنج. اعتبارًا من الإصدار 50 من Chrome (وفي الإصدار 42 من Firefox والإصدارات الأحدث)، لديك الآن خيار آخر: createImageBitmap()
. يتيح لك هذا الإجراء فك ترميز صورة في الخلفية والوصول إلى شكل ImageBitmap
أولي جديد يمكنك رسمه على لوحة الرسم بالطريقة نفسها التي ترسم بها عنصر <img>
أو لوحة رسم أخرى أو فيديو.
رسم أشكال مبعثرة باستخدام createImageBitmap()
لنفترض أنّك نزّلت صورة ملفّ مضغوط باستخدام fetch()
(أو XHR)، وتريد رسمها على لوحة. بدون createImageBitmap()
، عليك إنشاء عنصر صورة وعنوان URL لملف Blob لتحويل الصورة إلى تنسيق يمكنك استخدامه. باستخدامه، يمكنك الحصول على مسار مباشر أكثر للرسم:
fetch(url)
.then(response => response.blob())
.then(blob => createImageBitmap(blob))
.then(imageBitmap => ctx.drawImage(imageBitmap, 0, 0));
سيعمل هذا النهج أيضًا مع الصور المخزّنة كبيانات غير منتظمة في IndexedDB، ما يجعل البيانات غير المنتظمة تنسيقًا وسيطًا مناسبًا. يتوافق الإصدار 50 من Chrome أيضًا مع طريقة .toBlob()
في عناصر اللوحة، ما يعني أنّه يمكنك مثلاً إنشاء مجموعات نقاط من عناصر اللوحة.
استخدام createImageBitmap() في مهام Worker على الويب
من أجمل ميزات createImageBitmap()
أنّه متاح أيضًا في "العامل"، ما يعني أنّه يمكنك الآن فك ترميز الصور في أي مكان تريده. إذا كانت لديك الكثير من الصور التي تعتقد أنّها غير ضرورية ويجب فك ترميزها، يمكنك إرسال عناوين URL الخاصة بها إلى Web Worker الذي سينزّلها ويفكّ تشفيرها حسب الوقت المتاح. وبعد ذلك، ستتم إعادة نقلها إلى سلسلة المحادثات الرئيسية للرسم على لوحة.
قد يبدو الرمز البرمجي لإجراء ذلك على النحو التالي:
// In the worker.
fetch(imageURL)
.then(response => response.blob())
.then(blob => createImageBitmap(blob))
.then(imageBitmap => {
// Transfer the imageBitmap back to main thread.
self.postMessage({ imageBitmap }, [imageBitmap]);
}, err => {
self.postMessage({ err });
});
// In the main thread.
worker.onmessage = (evt) => {
if (evt.data.err)
throw new Error(evt.data.err);
canvasContext.drawImage(evt.data.imageBitmap, 0, 0);
}
في الوقت الحالي، إذا استدعت createImageBitmap()
في سلسلة التعليمات الرئيسية، سيتمّ فك التشفير في هذا المكان بالضبط. ومع ذلك، من المخطّط أن يُجري Chrome عملية فك التشفير تلقائيًا في سلسلة تعليمات أخرى، ما يساعد في تقليل عبء العمل في سلسلة التعليمات الرئيسية. في الوقت الحالي، يجب الانتباه إلى عملية فك التشفير في سلسلة المهام الرئيسية، لأنّها عملية كثيفة يمكن أن تحظر مهام أساسية أخرى، مثل JavaScript أو عمليات حساب الأنماط أو التنسيق أو الرسم أو الدمج.
مكتبة مساعدة
لتسهيل الأمر، أنشأتُ مكتبة مساعدة تعالج عملية فك التشفير في أحد خيوط العمل، وتعيد الصورة التي تم فك تشفيرها إلى الخيط الرئيسي، وترسمها على لوحة. يمكنك بالطبع إجراء هندسة عكسية للنموذج وتطبيقه على تطبيقاتك. تكمن الميزة الرئيسية في إمكانية التحكّم بشكل أكبر، ولكن (كالعادة) تتضمّن المزيد من الرموز البرمجية وتتطلب المزيد من عمليات تصحيح الأخطاء والحالات الهامشية التي يجب أخذها في الاعتبار مقارنةً باستخدام عنصر <img>
.
إذا كنت بحاجة إلى مزيد من التحكّم في فك ترميز الصور، فإنّ createImageBitmap()
هو أفضل صديق لك. يمكنك الاطّلاع على هذه الميزة في الإصدار 50 من Chrome وإخبارنا بتجربتك.