ב-Google, אנחנו כל הזמן מחפשים דרכים לגרום לדפי אינטרנט להיטען מהר יותר. אחת הדרכים לעשות זאת היא להקטין תמונות מהאינטרנט. התמונות מורכבות מ-60%-65% מהבייטים ברוב דפי האינטרנט, וגודל הדף הוא גורם משמעותי בזמן העיבוד הכולל. גודל הדף חשוב במיוחד לניידים, כי תמונות קטנות יותר חוסכות גם ברוחב הפס וגם בחיי הסוללה.
WebP הוא פורמט תמונה חדש שפותח על ידי Google והוא נתמך ב-Chrome, ב-Opera וב-Android. הוא עבר אופטימיזציה כדי לאפשר תמונות קטנות ומהירות יותר באינטרנט. הגודל של תמונות WebP קטן ב-30% בהשוואה לתמונות בפורמט PNG ו-JPEG ובאיכות הוויזואלית זהה. נוסף על כך, פורמט התמונה WebP תואם גם לתכונות של פורמטים אחרים. הוא תומך בתכונות הבאות:
דחיסת נתונים (Lossy): הדחיסה עם אובדן נתונים מבוססת על קידוד הפריימים של המפתח VP8. VP8 הוא פורמט דחיסת וידאו שנוצר על ידי On2 Technologies כתחליף לפורמט VP6 ו-VP7.
דחיסת נתונים ללא אובדן: פורמט הדחיסה ללא אובדן נתונים פותח על ידי צוות WebP.
שקיפות: ערוץ אלפא של 8 ביט שימושי לתמונות גרפיות. אפשר להשתמש בערוץ האלפא יחד עם RGB עם אובדן נתונים, תכונה שכרגע לא זמינה בפורמטים אחרים.
אנימציה: היא תומכת בתמונות מונפשות בצבע אמיתי.
מטא-נתונים: עשויים להיות מטא-נתונים של EXIF ו-XMP (לדוגמה, בשימוש במצלמות).
פרופיל צבע: יכול להיות שיש בו פרופיל ICC מוטמע.
בגלל דחיסה טובה יותר של תמונות ותמיכה בכל התכונות האלה, WebP יכול להיות תחליף מצוין לרוב הפורמטים של התמונות: PNG, JPEG או GIF. יותר מכך, ידעתם ש-WebP מאפשר הזדמנויות חדשות לאופטימיזציה של תמונות, כמו תמיכה בתמונות עם אובדן באמצעות שקיפות? כן. WebP היא סכין צבא שוויצרית עם פורמטים של תמונות.
אז איך הקסם הזה מתבצע? בואו נתחיל לעשות שרוולים כדי לראות מה קורה מאחורי הקלעים.
WebP אובדן
דחיסת הנתונים עם אובדן נתונים ב-WebP משתמשת באותה מתודולוגיה שבה נעשה שימוש ב-VP8 לחיזוי פריימים (וידאו). VP8 מבוסס על חיזוי חסימה וכמו כל קודק מבוסס בלוקים, VP8 מחלק את המסגרת לקטעים קטנים יותר שנקראים מאקרוblocks.
בתוך כל מאקרו, המקודד יכול לחזות מידע מיותר על תנועה וצבע על סמך בלוקים שעובדו בעבר. מסגרת התמונה היא "מפתח" בכך שהיא משתמשת בפיקסלים שכבר מפוענחו בסביבה המרחבית המיידית של כל אחד מבלוקי המאקרו, ומנסה למלא את החלק הלא ידוע שלהם. התהליך הזה נקרא קידוד חזוי (מידע נוסף זמין במאמר קידוד בתוך פריים של סרטון VP8).
לאחר מכן ניתן להחסיר את הנתונים המיותרים מהבלוק, וכתוצאה מכך הדחיסה יעילה יותר. נותר לנו רק הפרש קטן, שנקרא שיורי, להעברה בצורה דחוסה.
אחרי שעברתם לבצע טרנספורמציה מתמטית שלא ניתנת להיפוך (ה-DCT המפורסם, שנקרא 'טרנספורמציה קוסינית בדידה'), שאריות בדרך כלל מכילות ערכי אפס רבים, שאפשר לדחוס אותם בצורה יעילה יותר. לאחר מכן, התוצאה מקודדת באמצעות קוונטיות ואנטרופיה. למרבה המזל, שלב הקוונטיזציה הוא היחיד שבו הביטים נמחקים בצורה אוטומטית (מחפשים את החלוקה ב-QPj בתרשים הבא). כל שאר השלבים הם בלתי הפיכים וללא אובדן!
בתרשים הבא מוצגים השלבים בדחיסת נתונים עם אובדן WebP. המאפיינים שמבדלים את המשתמשים לעומת JPEG מסומנים בעיגול באדום.
טכנולוגיית WebP משתמשת בקוונטיזציה של בלוקים ומפיצה סיביות באופן גמיש בין קטעי תמונה שונים: פחות ביטים לקטעי אנטרופיה נמוכים וביטים גבוהים יותר לקטעי אנטרופיה גבוהים יותר. WebP משתמש בקידוד אנטרופיה Arithmetic כדי להשיג דחיסה טובה יותר בהשוואה לקידוד Huffman המשמש ב-JPEG.
מצבי חיזוי בתוך VP8
מצבי חיזוי בתוך VP8 משמשים עם שלושה סוגים של מאקרוblock:
- 4x4 luma
- 16x16 luma
- כרומה 8x8
המאקרו-בלוקים הבאים משתפים איתם ארבעה מצבי חיזוי נפוצים:
H_PRED (חיזוי אופקי). ממלא כל עמודה בבלוק בעותק של העמודה השמאלית, L.
V_PRED (חיזוי אנכי). ממלא כל שורה בבלוק בעותק של השורה שלמעלה, A.
DC_PRED (חיזוי DC). מילוי הבלוק בערך יחיד באמצעות ממוצע הפיקסלים בשורה מעל A והעמודה שמשמאל ל-L.
TM_PRED (חיזוי TrueMotion). מצב שהשם שלו נובע משיטת דחיסה ששפותחה על ידי On2 Technologies. בנוסף לשורה A ועמודה L, הפרמטר TM_PRED משתמש בפיקסל P שמעל ומשמאל לבלוק. הבדלים אופקיים בין פיקסלים ב-A (החל מ-P) מופצים באמצעות הפיקסלים מ-L כדי להתחיל כל שורה.
בתרשים הבא מוצגים מצבי החיזוי השונים שמשמשים לדחיסת WebPlossy.
לבלוקים מסוג 4x4 luma, יש שישה מצבי פנים נוספים שדומים ל-V_PRED ול-H_PRED, אבל תואמים לחיזוי של הפיקסלים בכיוונים שונים. פרטים נוספים על המצבים האלה זמינים במדריך VP8 Bitstream.
קונטיזציה של בלוקים גמישים
כדי לשפר את האיכות של התמונה, אנחנו מפולחים אותה לאזורים שיש בהם תכונות דומות. בכל אחד מהפלחים האלה, הפרמטרים של הדחיסה (שלבי הקוונטיזציה, עוצמת הסינון וכו') מכוונים בנפרד. כך אפשר לבצע דחיסה יעילה על ידי פיזור מחדש של הביטים למקום השימושי ביותר. VP8 מאפשר עד ארבעה קטעים (הגבלה על זרם ה-bitstream של VP8).
למה WebP (lossy) טוב יותר מ-JPEG
קידוד החיזוי הוא הסיבה העיקרית לניצחון של WebP על פני JPEG. גם קוונטיציית בלוקים שניתנת להתאמה עושה את כל ההבדל. הסינון עוזר בקצב העברת נתונים בינוני/נמוך. קידוד אריתמטי בוליאני מספק רווחי דחיסה של 5%-10% בהשוואה לקידוד Huffman.
WebP ללא אובדן נתונים
הקידוד ללא WebP-lossless מבוסס על טרנספורמציה של התמונה באמצעות מספר שיטות שונות. לאחר מכן מתבצע קידוד אנטרופיה על הפרמטרים של הטרנספורמציה ועל נתוני התמונה שעברו טרנספורמציה. הטרנספורמציות שחלות על התמונה כוללות חיזוי מרחבי של פיקסלים, טרנספורמציה של מרחב צבעים, שימוש בלוחות צבעים מתפתחים באופן מקומי, אריזה של מספר פיקסלים לפיקסל אחד והחלפת האלפא. לצורך קידוד האנטרופיה אנחנו משתמשים בווריאנט של קידוד LZ77-Huffman, שמשתמש בקידוד דו-ממדי של ערכי מרחק וערכים קומפקטיים.
טרנספורמציה של חיזוי (מרחבי)
חיזוי מרחבי משמש להפחתת האנטרופיה על ידי ניצול העובדה שפיקסלים קרובים הם לעיתים קרובות מתואמים. בטרנספורמציה של החיזוי, ערך הפיקסלים הנוכחי צפוי על סמך הפיקסלים שכבר מפוענחו (בסדר שורת הסריקה), ורק הערך השיורי (בפועל - חזוי) מקודד. מצב החיזוי קובע את סוג החיזוי שבו ייעשה שימוש. התמונה מחולקת לכמה אזורים ריבועיים, וכל הפיקסלים בריבוע אחד משתמשים באותו מצב חיזוי.
קיימים 13 מצבי חיזוי אפשריים שונים. הערכים השכיחים הם פיקסלים משמאל, למעלה, בצד שמאל למעלה ובצד ימין למעלה. שאר הערכים הם שילובים (ממוצעים) של משמאל, למעלה, למעלה משמאל ולמעלה.
טרנספורמציה של צבעים (ביטול מתאם)
המטרה של התמרת הצבע היא לעצב את הקשר בין ערכי R, G ו-B לכל פיקסל. טרנספורמציית צבע שומרת את הערך הירוק (G) כפי שהוא, משנה את הצבע האדום (R) על בסיס ירוק, משנה את הצבע לכחול (B) על בסיס ירוק ואז לפי אדום.
כמו במקרה של הטרנספורמציה החזויה, קודם התמונה מחולקת לבלוקים ואותו מצב טרנספורמציה משמש לכל הפיקסלים בבלוק. בכל בלוק יש שלושה סוגים של אלמנטים של המרת צבע: ירוק_לאדום, ירוק לכחול ואדום_לכחול.
החסירו בין הטרנספורמציה הירוקה
הפעולה "הקטנה של הטרנספורמציה הירוקה" מחסירה את הערכים הירוקים מהערכים האדום והכחול של כל פיקסל. כשהטרנספורמציה הזו קיימת, המפענח צריך להוסיף את הערך הירוק גם לאדום וגם לכחול. זה מקרה מיוחד של הטרנספורמציה הכללית של עיטור הצבעים שלמעלה, בתדירות מספיק גבוהה כדי להקפיץ את המודל.
טרנספורמציה של יצירת אינדקס צבעים (פלטות)
אם אין הרבה ערכי פיקסלים ייחודיים, יכול להיות שיהיה יעיל יותר ליצור מערך של אינדקס צבעים ולהחליף את ערכי הפיקסלים באינדקסים של המערך. כך ניתן לעשות זאת באמצעות הטרנספורמציה של יצירת האינדקס. הטרנספורמציה של הוספת הצבעים לאינדקס בודקת את מספר ערכי ה-ARGB הייחודיים בתמונה. אם המספר קטן מערך סף (256), הוא יוצר מערך של ערכי ה-ARGB האלה, שלאחר מכן משמש להחלפת ערכי הפיקסלים באינדקס המתאים.
קידוד מטמון צבע
בדחיסת WebP ללא אובדן נתונים נעשה שימוש במקטעי תמונה שכבר הוצגו כדי ליצור פיקסלים חדשים. ניתן גם להשתמש בלוח צבעים מקומי אם לא נמצאה התאמה מעניינת. לוח הצבעים הזה מתעדכן כל הזמן כדי לעשות שימוש חוזר בצבעים האחרונים. בתמונה למטה ניתן לראות מטמון הצבעים המקומי בפעולה מתעדכנת בהדרגה עם 32 הצבעים שהיו בשימוש לאחרונה, ככל שהסריקה יורדת למטה.
הפניה לאחור LZ77
הפניות לאחור הן צמדים של קוד אורך ומרחק. האורך מציין כמה פיקסלים יש להעתיק בשורת הסריקה. קוד המרחק הוא מספר שמציין את המיקום של פיקסל שנראה בעבר, שממנו יש להעתיק את הפיקסלים. ערכי האורך והמרחק נשמרים באמצעות קוד התחילית LZ77.
קידוד הקידומת LZ77 מחלק ערכים של מספרים שלמים גדולים לשני חלקים: קוד הקידומת והביטים הנוספים. קוד התחילית מאוחסן באמצעות קוד אנטרופיה, בעוד שהביטים הנוספים נשמרים כפי שהם (ללא קוד אנטרופיה).
בתרשים הבא מוצגת דוגמה ל-LZ77 (וריאציה דו-ממדית) עם התאמת מילים (במקום בפיקסלים).
WebP אובדן עם אלפא
בנוסף ל-WebP עם אובדן נתונים (צבעי RGB) ול-WebP ללא אובדן (RGB ללא אובדן עם אלפא), קיים מצב WebP נוסף שמאפשר קידוד אובדן לערוצי RGB וקידוד ללא אובדן לערוץ האלפא. אפשרות כזאת (Losy RGB ו-lossless alpha) לא זמינה היום באף אחד מהפורמטים הקיימים של התמונות. כיום, מנהלי אתרים שצריכים שקיפות צריכים לקודד תמונות בפורמט PNG ללא אובדן, מה שמוביל לעלייה משמעותית בנפח. טכנולוגיית WebP alpha מקודדת תמונות עם ביטים נמוכים לכל פיקסל, ומספקת דרך יעילה להקטין את הגודל של התמונות האלה. דחיסה ללא אובדן נתונים של ערוץ האלפא מוסיפה 22% בייטים בלבד לעומת קידוד WebP עם אובדן (איכות 90).
באופן כללי, החלפת PNG שקוף ב-WebP עם אובדן + אלפא משפרת את הגודל בממוצע של 60-70%. מסתבר שמדובר בפיצ'ר אטרקטיבי במיוחד לאתרים לנייד עם הרבה סמלים (לדוגמה, everything.me).