עיבוד תמונות בצד הלקוח בביצועים גבוהים

עיבוד תמונות בדפדפן הוא כיום דרישה סטנדרטית. ייתכן שתבנו עורכי תמונות, ערכות כלים לנכסים (asset toolkits) או מסנני נגישות. כדי לשמור על ממשק משתמש (UI) מגיב, עליכם להבטיח זמן תגובה (latency) נמוך.

משימה פשוטה היא היפוך צבעים. המשמעות היא הפיכת ערכי RGB לערכים השליליים שלהם. אם תשתמשו בגישה הסטנדרטית על תמונות 4K, תיתקלו בצווארי בקבוק של החומרה.

הבעיה: איטרציה נאיבית

רוב המפתחים משתמשים במתודה getImageData(). היא מחזירה Uint8ClampedArray. מערך זה שומר פיקסלים כערוצי Red, Green, Blue, ו-Alpha (RGBA).

לולאה סטנדרטית נראית כך:

זה עובד עבור תמונות קטנות. זה נכשל עבור נכסי 4K. לתמונה ב-4K יש למעלה מ-8 מיליון פיקסלים. לולאה סטנדרטית מבצעת למעלה מ-33 מיליון כתיבות נפרדות. זה חוסם את ה-main thread, גורם לקפיעות בדפדפן ולדילוג על פריימים (drops frames).

הפתרון: מניפולציה של Buffer ב-32 סיביות

אתם יכולים להפסיק להתייחס לפיקסלים כארבעה ערוצים נפרדים. במקום זאת, הניחו Uint32Array מעל ה-data buffer.

באמצעות שימוש ב-view של 32 סיביות, אתם מקבצים את R, G, B, ו-A למספר שלם אחד. הלולאה שלכם מבצעת כעת רק 8.2 מיליון איטרציות במקום 33 מיליון. אתם מבצעים פעולה אחת לכל פיקסל במקום ארבע.

היפוך צבעים מהיר באמצעות Bitwise XOR

כדי להפוך צבעים מבלי לגעת ב-Alpha, השתמשו באופרטור ה-bitwise XOR (^). השתמשו ב-mask 0x00FFFFFF.

איך זה עובד:

התוצאות:

טיפ של מקצוענים: השתמשו ב-Web Workers

אם אתם מעבדים קבצים רבים ברזולוציה גבוהה, אפילו פעולות של 32 סיביות עלולות להאט את ה-UI. העבירו את הלוגיקה ל-Web Worker. השתמשו ב-Transferable Objects כדי להעביר את ה-buffer. זה מונע העתקת נתונים ושומר על ה-main thread שלכם פנוי.

הפסיקו להשתמש בלולאות כבדות. השתמשו ב-32-bit words וב-bitwise flags כדי לבנות pipelines של תמונות רזים ומהירים.

מקור: https://dev.to/sharjeel360/high-performance-client-side-image-processing-optimizing-canvas-color-inversion-with-uint32array-1bgg