פורמטים של תמונות: WebP

Google פיתחה במקור את WebP כפורמט תמונה עם אובדן אבד, שיחליף את פורמט JPEG, שיכול היה ליצור קבצים קטנים יותר מקובץ תמונה באיכות דומה המקודד כ-JPEG. עדכונים מאוחרים יותר של הפורמט מציגים את האפשרות של דחיסה ללא אובדן נתונים, שקיפות ערוץ אלפא דמוי PNG, ואנימציה דמוית GIF - ניתן להשתמש בכל האפשרויות האלו לצד דחיסה עם אובדן נתונים בסגנון JPEG. WebP הוא פורמט מגוון מדהים.

האלגוריתם של דחיסת נתוני אובדן נתונים של WebP מבוסס על שיטה שבה משתמש קודק הווידאו VP8 כדי לדחוס תמונות מפתח בסרטונים. ברמה גבוהה, התהליך דומה לקידוד JPEG: WebP פועל בהקשר של 'בלוקים' ולא בתור פיקסלים בודדים, ויש לו חלוקה דומה בין רמת הבהירות לכרונומיה. בלוקי הלומה של WebP הם בגודל 16x16, ואילו בלוקי Chroma הם בגודל 8x8, וה"מקרובלוקים" האלה מחולקים יותר לבלוקי משנה של 4x4.

ההבדלים העיקריים בין WebP לבין JPEG הם שתי תכונות: "חיזוי חסימה" ו "קוונטיזציה של בלוקים גמישים".

חסימת החיזוי

חיזוי בלוקים הוא התהליך שבו חזוי את התוכן של כל בלוק של כרומנציה ותאורה על סמך הערכים של הבלוקים שמסביבם, ובמיוחד הבלוקים שמעל ומשמאל לבלוק הנוכחי. כפי שאתם יכולים לדמיין, האלגוריתמים שמבצעים את הפעולה הזו מורכבים למדי, אבל במילים פשוטות: "אם יש כחול מעל הבלוק הנוכחי וכחול משמאל לבלוק הנוכחי, נניח שהבלוק הזה כחול".

למעשה, גם חיזוי מסוג PNG וגם JPEG מתבצע במידה מסוימת של חיזוי. עם זאת, WebP הוא ייחודי בכך שהוא דוגם את הנתונים של הבלוקים שמקיפים אותו, ואז מנסה לאכלס את הבלוק הנוכחי בכמה 'מצבי חיזוי' שונים, בניסיון "לצייר" את החלק החסר בתמונה. לאחר מכן, המערכת משווה בין התוצאות שמתקבלות בכל מצב חיזוי לבין נתוני התמונה האמיתיים, ונבחרה ההתאמה החזויה הקרובה ביותר.

תרשים של השיטות השונות לחיזוי בלוקים של WebP.

גם ההתאמה החזויה הקרובה ביותר לא תהיה מדויקת לחלוטין, כמובן, כך שההבדלים בין הערכים החזויים לערכים בפועל של הבלוק הזה מקודדים בקובץ. במהלך פענוח התמונה, מנוע הרינדור משתמש באותם נתונים כדי להחיל את אותה לוגיקת חיזוי, שמובילה לאותם ערכים חזויים בכל בלוק. ההבדל בין החיזוי לבין התמונה הצפויה שקודדה בקובץ מוחל לאחר מכן על החיזויים - בדומה לאופן שבו פעולת Git Bard מייצגת תיקון דיפרנציאלי המוחל על הקובץ המקומי, במקום עותק חדש לגמרי של הקובץ.

כדי להמחיש זאת: במקום להתעמק במתמטיקה המורכבת שמעורבת באלגוריתם החיזוי האמיתי, נמציא קידוד דמוי WebP עם מצב חיזוי יחיד, ונשתמש בו כדי להעביר ביעילות רשת מספרים כמו שעשינו עם הפורמטים מהדור הקודם. לאלגוריתם שלנו יש מצב חיזוי יחיד, שנקרא "מצב חיזוי 1": הערך של כל בלוק הוא סכום הערכים של הבלוקים שמעליו ומשמאלו, מתחיל ב-1.

עכשיו נניח שאנחנו מתחילים עם נתוני התמונה האמיתיים הבאים:

111151111
122456389

אם נשתמש במודל החיזוי שלנו כדי לקבוע את התוכן של רשת בגודל 2x9, נקבל את התוצאה הבאה:

111111111
123456789

הנתונים שברשותנו מתאימים מאוד לאלגוריתם החיזוי שהמצאנו - הנתונים החזויים תואמים במידה רבה לנתונים האמיתיים שלנו. כמובן שאינה התאמה מושלמת - לנתונים בפועל יש מספר בלוקים ששונים מהנתונים החזויים. לכן, הקידוד שאנחנו שולחים כולל לא רק את שיטת החיזוי שבה צריך להשתמש, אלא גם הבדל בין בלוקים שאמורים להיות שונים מהערכים החזויים שלהם:

_ _ _ _ +4 _ _ _ _
_ _ -1 _ _ _ -4 _ _

השתמש באותה שפה פשוטה כמו חלק מהקידודים לפורמטים מדור קודם שהסברנו עליהם:

רשת של 2x9 עם מצב חיזוי 1. +4 עד 1x5, -1 עד 2x3, -4 עד 2x7.

התוצאה הסופית היא קובץ מקודד יעיל מלהיב.

קוונטיזציה של בלוקים מותאמים

דחיסת JPEG היא פעולה גורפת, המחילה את אותה רמה של כימות על כל בלוק בתמונה. בתמונה עם קומפוזיציה אחידה, הגיוני להבין – אבל תמונות מהעולם האמיתי הן לא יותר אחידות מהעולם שסביבנו. בפועל, פירוש הדבר הוא שהגדרות הדחיסה שלנו בפורמט JPEG לא נקבעות לפי הפרטים בתדירות גבוהה – היכן שמציאה של דחיסת JPEG – אלא לפי החלקים בתמונה שבהם סביר ביותר שיופיעו ארטיפקטים של דחיסה.

תמונת JPEG דחוסה של פרפר דנאית

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

כדי למנוע מצב כזה, WebP נוקט גישה מותאמת לקוונטיזציה: תמונה מחולקת לעד ארבעה פלחים דומים מבחינה חזותית, והפרמטרים של הדחיסה עבור הפלחים האלה מכוונים בנפרד. שימוש באותה דחיסה גדולה מאוד עם WebP:

תמונה דחוסה של WebP של פרפר דנאית

הגודל של שני קובצי התמונה האלה הוא פחות או יותר זהה. כשמסתכלים על כנפי המלך, אפשר לראות כמה הבדלים קטנים בתוצאה הסופית, אם מסתכלים מקרוב מאוד, אבל אין הבדל ממשי באיכות הכללית. ב-WebP, הפרחים של 'ענת החלב' קצת יותר חדים - שוב, סביר להניח שלא מספיק להבחין בהם אלא אם משווים בין שני הפרחים זה לצד זה, וממש מחפשים הבדלים באיכות, כמו שאנחנו. הרקע הוא סיפור אחר לגמרי: יש בו בקושי חותר למוצרים הבולטים לעין של JPEG. WebP מספק לנו את אותו גודל קובץ, אבל תמונה באיכות הרבה יותר גבוהה – ציינו או קחו כמה פרטים קטנטנים שהמערכות הפסיכו-ויזואליות שלנו לא יוכלו לזהות אם לא נשווה בין שני המצבים.

שימוש ב-WebP

החלקים הפנימיים של WebP עשויים להיות מורכבים יותר מקידוד JPEG, אבל הם פשוטים באותה מידה לצורך העבודה היומיומית שלנו: כל מורכבות הקידוד של WebP נקבעת על בסיס ערך "איכות" יחיד שמבוטא בין 0 ל-100, בדיוק כמו JPEG. שוב, זה לא אומר שאתם מוגבלים להגדרת 'איכות' כוללת אחת. אתם יכולים לצמצם את כל הפרטים הקטנים של קידוד WebP, ולו רק כדי להבין טוב יותר איך ההגדרות האלה, שבדרך כלל בלתי נראות, יכולות להשפיע על הגודל והאיכות של הקובץ.

Google מציעה מקודד שורת פקודה cwebp שמאפשר להמיר או לדחוס קבצים בודדים או ספריות שלמות של תמונות:

$ cwebp -q 80 butterfly.jpg -o butterfly.webp

Saving file 'butterfly.webp'
File:   butterfly.jpg
Dimension: 1676 x 1418
Output: 208418 bytes Y-U-V-All-PSNR 41.00 43.99 44.95   41.87 dB
        (0.70 bpp)
block count:    intra4:     7644  (81.80%)
               Intra16:     1701  (18.20%)
               Skipped:       63  (0.67%)
bytes used:  header:            249  (0.1%)
              mode-partition:  36885  (17.7%)
Residuals bytes  |segment 1|segment 2|segment 3|segment 4|  total
macroblocks:     |       8%|      22%|      26%|      44%|   9345
quantizer:       |      27 |      25 |      21 |      13 |
filter level:    |       8 |       6 |      19 |      16 |

ואם יש לכם כוונה להשתמש בשורת הפקודה, Squoosh ישמש אותנו באותה מידה לקידוד WebP. בכלי הזה יש אפשרות לבצע השוואות זו לצד זו בין קידודים, הגדרות, רמות איכות והבדלים בגודל הקבצים בהשוואה לקידוד JPEG.