Chrome mendukung createImageBitmap() di Chrome 50

Decoding gambar untuk digunakan dengan kanvas adalah hal yang cukup umum, baik untuk memungkinkan pengguna menyesuaikan avatar, memangkas gambar, atau hanya memperbesar gambar. Masalah pada decoding gambar adalah bahwa hal tersebut dapat menggunakan CPU secara intensif, dan terkadang dapat berarti jank atau papan catur. Mulai Chrome 50 (dan di Firefox 42+), Anda kini memiliki opsi lain: createImageBitmap(). Library ini memungkinkan Anda mendekode gambar di latar belakang, dan mendapatkan akses ke primitif ImageBitmap baru, yang dapat digambar ke dalam kanvas dengan cara yang sama seperti elemen <img>, kanvas lain, atau video.

Menggambar blob dengan createImageBitmap()

Misalkan Anda mendownload gambar blob dengan fetch() (atau XHR), dan Anda ingin menggambarnya ke kanvas. Tanpa createImageBitmap(), Anda harus membuat elemen gambar dan URL Blob untuk membuat gambar ke format yang dapat digunakan. Dengan alat ini, Anda akan mendapatkan rute yang jauh lebih langsung untuk mengecat:

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

Pendekatan ini juga akan berfungsi dengan gambar yang disimpan sebagai blob di IndexedDB, sehingga blob menjadi format menengah yang praktis. Saat ini, Chrome 50 juga mendukung metode .toBlob() pada elemen kanvas, yang berarti Anda dapat, misalnya, menghasilkan blob dari elemen kanvas.

Menggunakan createImageBitmap() dalam pekerja web

Salah satu fitur terbaik createImageBitmap() adalah layanan ini juga tersedia dalam pekerja, yang berarti kini Anda dapat mendekode gambar di mana pun Anda mau. Jika Anda memiliki banyak gambar untuk didekode yang dianggap tidak penting, Anda akan mengirimkan URL-nya ke Pekerja Web, yang akan mendownload dan mendekodenya jika ada waktu. Kemudian akan ditransfer kembali ke thread utama untuk menggambar ke dalam kanvas.

Aliran data dengan createImageBitmap dan pekerja web.

Kode untuk melakukan ini mungkin terlihat seperti ini:

// 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);
}

Hari ini jika Anda memanggil createImageBitmap() pada thread utama, di sinilah dekode akan dilakukan. Namun, rencananya adalah Chrome secara otomatis melakukan dekode di thread lain, sehingga membantu menurunkan beban kerja thread utama. Namun, sementara itu, Anda harus berhati-hati dalam melakukan decoding pada thread utama, karena ini merupakan pekerjaan intensif yang dapat memblokir tugas penting lainnya, seperti JavaScript, penghitungan gaya, tata letak, proses menggambar, atau pengomposisian.

Library helper

Untuk memudahkan, saya telah membuat library helper yang menangani decoding pada pekerja, dan mengirimkan kembali gambar yang didekode ke thread utama, serta menggambarnya dalam kanvas. Tentu saja, Anda harus merekayasa baliknya dan menerapkan model ke aplikasi Anda sendiri. Manfaat utamanya adalah lebih banyak kontrol, tetapi (seperti biasa) dilengkapi dengan lebih banyak kode, lebih banyak hal untuk di-debug, dan lebih banyak kasus ekstrem untuk dipertimbangkan daripada menggunakan elemen <img>.

Jika Anda memerlukan lebih banyak kontrol dengan decoding gambar, createImageBitmap() adalah sahabat baru Anda. Coba lihat di Chrome 50, dan beri tahu kami cara Anda melakukannya.