يدعم Chrome createImageBitmap() في Chrome 50

إنّ فك ترميز الصور لاستخدامها مع لوحة صورة شائع جدًا، سواء كان ذلك للسماح للمستخدمين بتخصيص صورة رمزية أو اقتصاص صورة أو تكبير صورة فقط. تكمن مشكلة فك ترميز الصور في أنّها قد تستهلك الكثير من وحدة المعالجة المركزية، ما قد يؤدي أحيانًا إلى حدوث تقطُّع أو ظهور تأثير لوحة الشطرنج. اعتبارًا من الإصدار 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 الذي سينزّلها ويفكّ تشفيرها حسب الوقت المتاح. وبعد ذلك، ستتم إعادة نقلها إلى سلسلة المحادثات الرئيسية للرسم على لوحة.

تدفق البيانات باستخدام createImageBitmap وWeb Workers

قد يبدو الرمز البرمجي لإجراء ذلك على النحو التالي:

// 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 وإخبارنا برأيك.