Chrome รองรับ createImageBitmap() ใน Chrome 50

การถอดรหัสรูปภาพเพื่อใช้กับผืนผ้าใบเป็นเรื่องปกติ ไม่ว่าจะเป็นการอนุญาตให้ผู้ใช้ปรับแต่งรูปโปรไฟล์ ครอบตัดรูปภาพ หรือแค่ซูมเข้ารูปภาพ ปัญหาในการถอดรหัสรูปภาพคืออาจทำให้ CPU ทำงานหนัก และบางครั้งอาจหมายถึงการทำงานยากหรือการตรวจสอบบอร์ด ตั้งแต่ Chrome 50 (และใน Firefox 42 ขึ้นไป) คุณจะมีตัวเลือกใหม่คือ createImageBitmap() ฟีเจอร์นี้ช่วยให้คุณถอดรหัสรูปภาพในเบื้องหลังและรับสิทธิ์เข้าถึง ImageBitmap แบบเดิมแบบใหม่ได้ ซึ่งคุณจะวาดลงในผืนผ้าใบได้ในลักษณะเดียวกับที่ทำองค์ประกอบ <img>, ผืนผ้าใบอื่น หรือวิดีโอ

การวาด Blob ด้วย 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() ใน Web Worker

ฟีเจอร์ที่ดีที่สุดอย่างหนึ่งของ createImageBitmap() คือฟีเจอร์นี้ใช้งานได้สำหรับผู้ปฏิบัติงานด้วย ซึ่งหมายความว่าตอนนี้คุณสามารถถอดรหัสรูปภาพได้ทุกที่ที่ต้องการ หากคุณมีรูปภาพจำนวนมากที่ต้องถอดรหัสและเห็นว่าไม่จำเป็น คุณจะต้องจัดส่ง URL ของรูปภาพเหล่านั้นไปยัง Web Worker ซึ่งจะดาวน์โหลดและถอดรหัสตามเวลาที่เอื้ออำนวย จากนั้นระบบจะโอนผู้ใช้กลับไปยังชุดข้อความหลักเพื่อวาดลงในผืนผ้าใบ

การรับส่งข้อมูลด้วย 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 และบอกเราว่าคุณดำเนินการอย่างไรต่อไป