การถอดรหัสรูปภาพเพื่อใช้กับ Canvas นั้นพบได้ทั่วไป ไม่ว่าจะเป็นการอนุญาตให้ผู้ใช้ปรับแต่งรูปโปรไฟล์ ครอบตัดรูปภาพ หรือเพียงแค่ซูมเข้ารูปภาพ ปัญหาในการถอดรหัสภาพคือภาพที่ใช้ CPU หนักหน่วง และบางครั้งอาจหมายถึงการกระตุกหรือหมากรุก ตั้งแต่ Chrome เวอร์ชัน 50 (และใน Firefox เวอร์ชัน 42 ขึ้นไป) คุณจะมีตัวเลือกอื่นอีก นั่นคือ createImageBitmap()
ซึ่งจะช่วยให้คุณถอดรหัสรูปภาพในเบื้องหลังและเข้าถึงImageBitmap
Primitive ใหม่ได้ ซึ่งคุณสามารถวาดลงใน Canvas ได้เช่นเดียวกับองค์ประกอบ <img>
, Canvas อื่น หรือวิดีโอ
การวาดจุดด้วย createImageBitmap()
สมมติว่าคุณดาวน์โหลดรูปภาพ Blob ที่มี fetch()
(หรือ XHR) และต้องการวาดลงในผืนผ้าใบ หากไม่มี createImageBitmap()
คุณจะต้องสร้างองค์ประกอบรูปภาพและ URL ของ Blob เพื่อให้รูปภาพอยู่ในรูปแบบที่ใช้ได้ ซึ่งจะช่วยให้คุณวาดภาพได้โดยตรงมากขึ้น
fetch(url)
.then(response => response.blob())
.then(blob => createImageBitmap(blob))
.then(imageBitmap => ctx.drawImage(imageBitmap, 0, 0));
แนวทางนี้จะใช้ได้กับรูปภาพที่จัดเก็บเป็น Blob ใน IndexedDB ด้วย ซึ่งทำให้ Blob เป็นรูปแบบกลางที่สะดวก บังเอิญที่ Chrome 50 ยังรองรับเมธอด .toBlob()
ในองค์ประกอบ Canvas ด้วย ซึ่งหมายความว่าคุณจะสร้าง Blob จากองค์ประกอบ Canvas ได้ เป็นต้น
การใช้ createImageBitmap() ในเว็บเวิร์กเกอร์
ฟีเจอร์ที่ดีที่สุดอย่างหนึ่งของ createImageBitmap()
คือมีให้บริการสำหรับผู้ปฏิบัติงานด้วย ซึ่งหมายความว่าคุณจะถอดรหัสรูปภาพได้ทุกที่ที่ต้องการ หากมีรูปภาพจำนวนมากที่ต้องถอดรหัสซึ่งคุณคิดว่าไม่จำเป็น คุณจะต้องส่ง URL ของรูปภาพเหล่านั้นไปยัง Web Worker ซึ่งจะดาวน์โหลดและถอดรหัสรูปภาพดังกล่าวเมื่อมีโอกาส จากนั้นจะโอนกลับไปที่ชุดข้อความหลักเพื่อวาดลงในผืนผ้าใบ
โค้ดสำหรับการดำเนินการนี้อาจมีลักษณะดังนี้
// 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 แล้วบอกให้เราทราบถึงประสบการณ์การใช้งานของคุณ