פענוח תמונות לשימוש בקנבס הוא תהליך נפוץ למדי, בין אם הוא מאפשר למשתמשים להתאים אישית תמונת פרופיל, לחתוך תמונה או פשוט להתקרב לתמונה. הבעיה בפענוח תמונות היא שהיא יכולה להיות עתירה בשימוש במעבד, ולפעמים זה יכול לגרום לתנודות או לתמונות עם תבנית של משבצות. החל מגרסה 50 של Chrome (וגם ב-Firefox 42 ומעלה) יש לכם עכשיו אפשרות נוספת: createImageBitmap()
. הוא מאפשר לפענח תמונה ברקע ולקבל גישה לפרימיטיב ImageBitmap
חדש, שאפשר לצייר על לוח בדומה לאלמנט <img>
, ללוח אחר או לסרטון.
ציור כתמים באמצעות createImageBitmap()
נניח שאתם מורידים קובץ blob של תמונה באמצעות fetch()
(או XHR), ואתם רוצים לצייר אותו על קנבס. בלי createImageBitmap()
, תצטרכו ליצור רכיב תמונה וכתובת URL של Blob כדי להעביר את התמונה לפורמט שתוכלו להשתמש בו. בעזרתו תוכלו להגיע ישירות יותר לציור:
fetch(url)
.then(response => response.blob())
.then(blob => createImageBitmap(blob))
.then(imageBitmap => ctx.drawImage(imageBitmap, 0, 0));
הגישה הזו תפעל גם עם תמונות שמאוחסנות כ-blobs ב-IndexedDB, כך ש-blobs הם פורמט ביניים נוח. ב-Chrome 50 יש תמיכה גם בשיטה .toBlob()
ברכיבי Canvas, כך שאפשר, למשל, ליצור blobs מרכיבי Canvas.
שימוש ב-createImageBitmap() ב-web workers
אחת מהתכונות הטובות ביותר של createImageBitmap()
היא שהיא זמינה גם ב-workers, כך שאפשר עכשיו לפענח תמונות בכל מקום שרוצים. אם יש לכם הרבה תמונות לפענוח שאתם לא מחשיבן כחיוניות, תוכלו לשלוח את כתובות ה-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 ולספר לנו איך היא עובדת.