במקור Google פיתחה את WebP כפורמט תמונה עם אובדן נתונים, כדי להחליף את JPEG, פורמט שיכול להפיק קבצים קטנים יותר קובץ תמונה באיכות דומה המקודד בפורמט JPEG. בעדכונים מאוחרים יותר בפורמט הוספנו את האפשרות של דחיסה ללא אובדן נתונים, שקיפות ערוצים דמוית PNG בפורמט אלפא ואנימציה דמוית GIF. אפשר להשתמש בכל התכונות האלה לצד דחיסת נתונים מסוג JPEG בסגנון JPEG. WebP הוא פורמט מדהים ורב-שימושי.
אלגוריתם הדחיסה של נתוני WebP מסוג Lossy מבוסס על שיטה שקודק הווידאו VP8 משתמשת בו כדי לדחוס תמונות מפתח בסרטונים. ככלל, התכונה הזו דומה לקידוד JPEG: WebP פועל במונחים של 'בלוקים' במקום פיקסלים בודדים, ויש לו חלוקה דומה בין בהירות לבין בהירות. בלוקי הלומה של WebP הם בגודל 16x16, ואילו בלוקים של Chroma הם בגודל 8x8, ובלוקים האלה של microblocks הן בחלוקת משנה נוספת לגושי משנה בגודל 4x4.
כאשר WebP שונה באופן קיצוני מ-JPEG בשתי תכונות: 'חסימת חיזוי' ו"קונטיזציה של בלוקים גמישים".
חסימת החיזוי
חיזוי בלוקים הוא התהליך שבו ניתן לחזות את התוכן של כל בלוק של בהירות ושל הארה על סמך הערכים של הבלוקים שסביבו - במיוחד הבלוקים שמעל ומשמאל לבלוק הנוכחי. כמו שאפשר לדמיין, האלגוריתמים שעושים את העבודה הזו הן מורכבות יחסית, אבל בניסוח פשוט: "אם יש כחול מעל לבלוק הנוכחי וכחול משמאל של הבלוק הנוכחי, נניח שהבלוק הזה כחול."
למעשה, גם PNG וגם JPEG מבצעים חיזוי כזה במידה מסוימת. עם זאת, WebP הוא ייחודי בכך שהוא דוגמת את הסביבה בלוקים ואז מנסה לאכלס את הבלוק הנוכחי באמצעות מספר "מצבי חיזוי" שונים, תוך ניסיון למעשה "לצייר" את החלק החסר של התמונה. לאחר מכן מתבצעת השוואה בין התוצאות של כל מצב חיזוי לבין נתוני התמונה האמיתיים, והתוצאות הקרובות ביותר נבחרה ההתאמה החזויה.
גם ההתאמה החזויה הקרובה ביותר לא תהיה נכונה לגמרי, כמובן, לכן ההבדלים בין ההתאמה החזויה שהערכים בפועל של הבלוק הזה מקודדים בקובץ. במהלך פענוח התמונה, מנוע הרינדור משתמש באותם הנתונים כדי להחיל אותה לוגיקת חיזוי, שמובילה לאותם ערכים חזויים בכל בלוק. ההבדל בין החיזוי התמונה הצפויה אשר מקודדת בקובץ מיושמת לאחר מכן על החיזויים, בדומה לאופן שבו התחייבות Git מייצגת דיפרנציאל תיקון שיחול על הקובץ המקומי, ולא על עותק חדש לגמרי של הקובץ.
לצורך המחשה: במקום להתעמק במתמטיקה המורכבת הכרוכה באלגוריתם החיזוי האמיתי, אנחנו נמצא קידוד דמוי WebP במצב חיזוי אחד, ולהשתמש בו כדי להעביר באופן יעיל רשת של מספרים כמו שעשינו עם הפורמטים הקודמים. האלגוריתם שלנו יש מצב חיזוי יחיד, שנקרא 'מצב חיזוי 1': הערך של כל בלוק הוא סכום הערכים של הבלוקים שמעל ומשמאל, הוא מתחיל ב-1.
עכשיו נניח שאנחנו מתחילים בנתונים האמיתיים הבאים של תמונה:
111151111
122456389
באמצעות המודל החזוי שלנו כדי לקבוע את התוכן של רשת 2x9, נקבל את התוצאה הבאה:
111111111
123456789
הנתונים שלנו מתאימים לאלגוריתם החיזוי שהמצינו – הנתונים החזויים דומים לנתונים האמיתיים שלנו. אין התאמה מושלמת, כמובן – הנתונים בפועל כוללים מספר בלוקים שונים של הנתונים החזויים. ככה, הקידוד שאנחנו שולחים כולל לא רק את שיטת החיזוי שבה צריך להשתמש, אלא את ההבדל בין כל הבלוקים שאמורים להיות שונים מהערכים החזויים שלהם:
_ _ _ _ +4 _ _ _ _
_ _ -1 _ _ _ -4 _ _
כתובים באותו סוג של שפה פשוטה כמו כמה מהקידודים של הפורמטים הקודמים שעליהם דיברנו:
רשת של 2x9 באמצעות מצב חיזוי 1. +4 עד 1x5, -1 עד 2x3, -4 עד 2x7.
התוצאה הסופית היא קובץ מקודד ביעילות שלא ייאמן.
כימות בלוקים אדפטיבית
דחיסת JPEG היא פעולה כוללת, המחילה את אותה רמת קוונטיזציה על כל בלוק בתמונה. בתמונה שהמבנה שלהם אחיד, וזה הגיוני, אבל תמונות מהעולם האמיתי אינם אחידים יותר מהעולם שסביבנו. בפועל, זה אומר שהגדרות הדחיסה של JPEG שלנו נקבעות לא לפי פרטי התדר הגבוה — כאשר JPEG פעולת דחיסה מצוינת - אלא לפי החלקים בתמונה שבהם סביר להניח שיופיעו ארטיפקטים לאחר דחיסה.
כמו שאפשר לראות בדוגמה המוגזמת הזו, כנפי המלך בחזית נראות חדות יחסית – קצת מגורענות בהשוואה למקור ברזולוציה גבוהה, אבל בהחלט לא ניתן להבחין ללא מקור שאפשר להשוות אליו. בדומה לכך, התפרחות המפורטת של חלב החלב והעלים בחזית — אני ואני עשויים לראות עקבות של דחיסה באמצעות העיניים המאומנות שלנו, אבל גם כשהדחיסה התבצעה הרבה מעבר לרמה הסבירה של פריטים בחזית עדיין נקיות במידה סבירה. המידע שמופיע בתדירות נמוכה בפינה השמאלית העליונה של התמונה - הרקע הירוק המטושטש של העלים - נראה נוראי. אפילו צופה לא מיומן יבחין מיד בבעיית האיכות – ההדרגתיות העדינות ברקע מעוגלות כלפי מטה לבלוקים משוננים בצבע אחיד.
כדי למנוע מצב כזה, ה-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.