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 में भी कैनवस एलिमेंट से ब्लॉब जनरेट किया जा सकता है. इसका मतलब है कि कैनवस एलिमेंट पर, 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 में इसे देखें और हमें बताएं कि आपको यह सुविधा कैसे मिलेगी!