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 में देखें और हमें बताएं कि आप कैसे आगे बढ़ते हैं!