פענוח תמונות לשימוש בקנבס הוא תהליך נפוץ למדי, בין אם הוא מאפשר למשתמשים להתאים אישית תמונת פרופיל, לחתוך תמונה או פשוט להתקרב לתמונה. הבעיה בפענוחי תמונות היא שהם יכולים להיות עתירי מעבד, ולפעמים זה יכול לגרום לתנודות או לתמונות שתוצגו ברצף של משבצות. החל מגרסה 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() בעובדי אינטרנט
אחת מהתכונות הטובות ביותר של 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 ולספר לנו איך היא עובדת.