Chrome, Chrome 50 में createImageBitmap() के साथ काम करता है

कैनवस के साथ इस्तेमाल करने के लिए इमेज को डिकोड करना बहुत आम है. भले ही, लोगों को अवतार को पसंद के मुताबिक बनाने, इमेज को काटने या सिर्फ़ किसी तस्वीर पर ज़ूम इन करने की अनुमति दी जा रही हो. इमेज को डिकोड करने में सीपीयू का ज़्यादा इस्तेमाल होता है. इस वजह से, कभी-कभी इमेज में रुकावट आ सकती है या चेकरबोर्ड दिख सकता है. Chrome 50 और Firefox 42 और उसके बाद के वर्शन में, आपके पास अब एक और विकल्प है: createImageBitmap(). इसकी मदद से, बैकग्राउंड में मौजूद किसी इमेज को डिकोड किया जा सकता है. साथ ही, नए ImageBitmap प्राइमिटिव का ऐक्सेस भी मिलता है. इसे कैनवस में उसी तरह से ड्रॉ किया जा सकता है जिस तरह से <img> एलिमेंट, किसी दूसरे कैनवस या वीडियो को ड्रॉ किया जाता है.

createImageBitmap() का इस्तेमाल करके ब्लॉब बनाना

मान लें कि आपने fetch() (या XHR) की मदद से कोई ब्लॉब इमेज डाउनलोड की है और आपको उसे कैनवस पर ड्रॉ करना है. createImageBitmap() के बिना, आपको इमेज को इस्तेमाल किए जा सकने वाले फ़ॉर्मैट में लाने के लिए, इमेज एलिमेंट और ब्लॉब यूआरएल बनाना होगा. इसकी मदद से, पेंटिंग करने का तरीका सीखने में आपको ज़्यादा आसानी होती है:

fetch(url)
    .then(response => response.blob())
    .then(blob => createImageBitmap(blob))
    .then(imageBitmap => ctx.drawImage(imageBitmap, 0, 0));

यह तरीका, IndexedDB में ब्लॉब के तौर पर सेव की गई इमेज के साथ भी काम करेगा. इससे ब्लॉब, बीच में इस्तेमाल होने वाला एक आसान फ़ॉर्मैट बन जाएगा. Chrome 50, कैनवस एलिमेंट पर .toBlob() तरीके के साथ भी काम करता है. इसका मतलब है कि उदाहरण के लिए, कैनवस एलिमेंट से ब्लॉब जनरेट किए जा सकते हैं.

वेब वर्कर्स में createImageBitmap() का इस्तेमाल करना

createImageBitmap() की सबसे अच्छी सुविधाओं में से एक यह है कि यह वर्कर्स में भी उपलब्ध है. इसका मतलब है कि अब आपके पास इमेज को कहीं भी डिकोड करने का विकल्प है. अगर आपको ऐसी कई इमेज को डिकोड करना है जो आपके हिसाब से ज़रूरी नहीं हैं, तो उनके यूआरएल को वेब वर्कर्स पर भेजें. वे समय-समय पर इन्हें डाउनलोड करके डिकोड कर देंगे. इसके बाद, उन्हें कैनवस में ड्रॉ करने के लिए, मुख्य थ्रेड में वापस भेज दिया जाएगा.

createImageBitmap और वेब वर्कर्स की मदद से डेटा फ़्लो.

ऐसा करने के लिए, कोड कुछ ऐसा दिख सकता है:

// 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() आपका नया सबसे अच्छा दोस्त है. इसे Chrome 50 में आज़माएं और हमें बताएं कि आपका अनुभव कैसा रहा!