מה זה WebP? למה כדאי להשתמש בה?
WebP היא שיטה לדחיסת נתונים עם אובדן נתונים וללא אובדן נתונים, שאפשר להשתמש בה במגוון רחב של תמונות צילומיות, שקופות וגרפיות שנמצאות באינטרנט. אפשר לשנות את רמת הדחיסה עם אובדן נתונים, כך שהמשתמש יכול לבחור את האיזון בין גודל הקובץ לאיכות התמונה. בדרך כלל, פורמט WebP מאפשר דחיסה של 30% יותר נתונים בהשוואה לפורמטים JPEG ו-JPEG 2000, בלי לפגוע באיכות התמונה (ראו מחקר השוואתי).
פורמט WebP נועד ליצור תמונות קטנות יותר שנראות טוב יותר, כדי שהאינטרנט יהיה מהיר יותר.
אילו דפדפני אינטרנט תומכים ב-WebP באופן מובנה?
מנהלי אתרים שרוצים לשפר את ביצועי האתר יכולים ליצור בקלות חלופות WebP שעברו אופטימיזציה לתמונות הנוכחיות שלהם, ולהציג אותן בדפדפנים שתומכים ב-WebP על בסיס טירגוט.
- תמיכה ב-WebP עם אובדן נתונים
- Google Chrome (למחשב) גרסה 17 ואילך
- Google Chrome ל-Android גרסה 25 ומעלה
- Microsoft Edge 18+
- Firefox בגרסה 65 ומעלה
- Opera 11.10 ואילך
- דפדפן אינטרנט מובנה, Android 4.0 ואילך (ICS)
- Safari 14 ואילך (iOS 14 ואילך, macOS Big Sur ואילך)
- תמיכה ב-WebP lossy, lossless ובאלפא
- Google Chrome (למחשב) גרסה 23 ואילך
- Google Chrome ל-Android גרסה 25 ומעלה
- Microsoft Edge 18+
- Firefox בגרסה 65 ומעלה
- Opera 12.10 ואילך
- דפדפן אינטרנט מותאם, Android 4.2 ומעלה (JB-MR1)
- Pale Moon 26+
- Safari 14 ואילך (iOS 14 ואילך, macOS Big Sur ואילך)
- תמיכה באנימציות WebP
- Google Chrome (למחשב ול-Android) גרסה 32 ואילך
- Microsoft Edge 18+
- Firefox בגרסה 65 ומעלה
- Opera 19+
- Safari 14 ואילך (iOS 14 ואילך, macOS Big Sur ואילך)
ראה גם:
איך אפשר לזהות תמיכה ב-WebP בדפדפן?
מומלץ להציג תמונות WebP רק ללקוחות שיכולים להציג אותן בצורה תקינה, ולחזור לפורמטים מדור קודם עבור לקוחות שלא יכולים. למזלנו, יש כמה שיטות לזיהוי תמיכה ב-WebP, גם בצד הלקוח וגם בצד השרת. חלק מספקי CDN מציעים זיהוי תמיכה ב-WebP כחלק מהשירות שלהם.
משא ומתן על תוכן בצד השרת באמצעות כותרות Accept
בדרך כלל, לקוחות אינטרנט שולחים כותרת בקשה מסוג Accept, שמציינת אילו פורמטים של תוכן הם מוכנים לקבל בתגובה. אם דפדפן מציין מראש שהוא 'יקבל' את הפורמט image/webp, שרת האינטרנט יודע שהוא יכול לשלוח בבטחה תמונות WebP, וכך תהליך המשא ומתן על התוכן מתבצע בצורה פשוטה יותר. מידע נוסף זמין בקישורים הבאים.
Modernizr
Modernizr היא ספריית JavaScript שמאפשרת לזהות בקלות תמיכה בתכונות של HTML5 ו-CSS3 בדפדפני אינטרנט. מחפשים את המאפיינים Modernizr.webp, Modernizr.webp.lossless, Modernizr.webp.alpha ו-Modernizr.webp.animation.
רכיב HTML5 <picture>
HTML5 תומך ברכיב <picture>
, שמאפשר לכם לפרט כמה תמונות חלופיות לטירגוט בסדר עדיפות, כך שהלקוח יבקש את התמונה הראשונה שמועמדת להצגה בצורה תקינה. אפשר לעיין בדיון הזה ב-HTML5 Rocks. התמיכה ברכיב <picture>
מתרחבת כל הזמן לדפדפנים נוספים.
ב-JavaScript שלכם
שיטה נוספת לזיהוי היא לנסות לפענח תמונת WebP קטנה מאוד שמשתמשת בתכונה מסוימת, ולבדוק אם הפענוח הצליח. דוגמה:
// check_webp_feature:
// 'feature' can be one of 'lossy', 'lossless', 'alpha' or 'animation'.
// 'callback(feature, result)' will be passed back the detection result (in an asynchronous way!)
function check_webp_feature(feature, callback) {
var kTestImages = {
lossy: "UklGRiIAAABXRUJQVlA4IBYAAAAwAQCdASoBAAEADsD+JaQAA3AAAAAA",
lossless: "UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==",
alpha: "UklGRkoAAABXRUJQVlA4WAoAAAAQAAAAAAAAAAAAQUxQSAwAAAARBxAR/Q9ERP8DAABWUDggGAAAABQBAJ0BKgEAAQAAAP4AAA3AAP7mtQAAAA==",
animation: "UklGRlIAAABXRUJQVlA4WAoAAAASAAAAAAAAAAAAQU5JTQYAAAD/////AABBTk1GJgAAAAAAAAAAAAAAAAAAAGQAAABWUDhMDQAAAC8AAAAQBxAREYiI/gcA"
};
var img = new Image();
img.onload = function () {
var result = (img.width > 0) && (img.height > 0);
callback(feature, result);
};
img.onerror = function () {
callback(feature, false);
};
img.src = "data:image/webp;base64," + kTestImages[feature];
}
שימו לב: טעינת התמונות לא חוסמת את הטעינה של רכיבים אחרים והיא אסינכרונית. המשמעות היא שמומלץ להוסיף את כל הקוד שתלוי בתמיכה ב-WebP לפונקציית הקריאה החוזרת.
למה Google פרסמה את WebP כקוד פתוח?
אנחנו מאמינים מאוד בחשיבות של מודל הקוד הפתוח. הפורמט WebP הוא קוד פתוח, כך שכל אחד יכול לעבוד איתו ולהציע שיפורים. אנחנו מאמינים שעם ההצעות וההערות שלכם, השימוש ב-WebP כפורמט גרפי יהפוך ליעיל עוד יותר עם הזמן.
איך אפשר להמיר קבצים של תמונות אישיות ל-WebP?
אפשר להשתמש בכלי השירות WebP בשורת הפקודה כדי להמיר את קובצי התמונות האישיים לפורמט WebP. פרטים נוספים מופיעים במאמר שימוש ב-WebP.
אם יש לכם הרבה תמונות להמרה, אתם יכולים להשתמש במעטפת של הפלטפורמה כדי לפשט את הפעולה. לדוגמה, כדי להמיר את כל קובצי ה-JPEG בתיקייה, מנסים את הפקודה הבאה:
Windows:
> for /R . %I in (*.jpg) do ( cwebp.exe %I -o %~fnI.webp )
Linux / macOS:
$ for F in *.jpg; do cwebp $F -o `basename ${F%.jpg}`.webp; done
איך אפשר לבדוק את איכות התמונה בפורמט WebP?
בשלב הזה, אפשר להציג קובצי WebP על ידי המרה שלהם לפורמט נפוץ שמשתמש בדחיסה ללא אובדן נתונים, כמו PNG, ואז להציג את קובצי ה-PNG בכל דפדפן או כלי לצפייה בתמונות. כדי לקבל מושג מהיר לגבי האיכות של WebP, אפשר לעיין בגלריה באתר הזה כדי לראות השוואות בין תמונות.
איך מקבלים את קוד המקור?
קוד ההמרה זמין בקטע ההורדות בדף של פרויקט הקוד הפתוח WebP. הקוד של המפענח הקל והמפרט של VP8 נמצאים באתר WebM. למפרט של הקונטיינר, אפשר לעיין בדף RIFF Container.
מה הגודל המקסימלי של תמונה בפורמט WebP?
פורמט WebP תואם ל-VP8 מבחינת זרם הביטים, והוא משתמש ב-14 ביטים לרוחב ולגובה. הגודל המקסימלי של תמונה בפורמט WebP הוא 16,383x16,383 פיקסלים.
באילו מרחבי צבעים פורמט WebP תומך?
בדומה ל-VP8 bitstream, lossy WebP פועל באופן בלעדי עם פורמט תמונה של 8 ביט Y'CbCr 4:2:0 (שנקרא לעיתים קרובות YUV420). פרטים נוספים זמינים בסעיף 2, סקירה כללית של הפורמט, של RFC 6386, מדריך לפענוח ופורמט נתונים של VP8.
WebP ללא אובדן נתונים פועל רק עם פורמט RGBA. אפשר לעיין במפרט של WebP Lossless Bitstream.
למה יש הבדל בין קובץ WebP ללא אובדן נתונים לבין הקובץ המקורי?
הפונקציות של Simple Encoding API (WebPEncodeLosslessRGB()
, WebPEncodeLosslessBGR()
, WebPEncodeLosslessRGBA()
, WebPEncodeLosslessBGRA()
) משתמשות בהגדרות ברירת המחדל של הספרייה. במקרה של המרה ללא אובדן נתונים, האפשרות 'מדויק' מושבתת. ערכי RGB באזורים שקופים לחלוטין (כלומר, אזורים עם ערכי אלפא ששווים ל-0
) ישונו כדי לשפר את הדחיסה. כדי למנוע את הבעיה הזו, צריך להשתמש ב-WebPEncode()
ולהגדיר את WebPConfig::exact
ל-1
. מידע נוסף זמין במאמר בנושא Advanced Encoding API.
האם תמונת WebP יכולה להיות גדולה יותר מתמונת המקור שלה?
כן, בדרך כלל כשממירים מפורמט עם אובדן נתונים לפורמט WebP ללא אובדן נתונים או להיפך. הסיבה העיקרית לכך היא ההבדל במרחב הצבעים (YUV420 לעומת ARGB) וההמרה ביניהם.
יש שלושה מצבים אופייניים:
- אם תמונת המקור היא בפורמט ARGB ללא אובדן נתונים, הדגימה המרחבית למטה ל-YUV420 תוסיף צבעים חדשים שקשה יותר לדחוס אותם מאשר את הצבעים המקוריים. המצב הזה יכול לקרות בדרך כלל כשהמקור הוא בפורמט PNG עם מעט צבעים: המרה ל-WebP עם אובדן נתונים (או באופן דומה ל-JPEG עם אובדן נתונים) עלולה להוביל לגודל קובץ גדול יותר.
- אם המקור הוא בפורמט עם אובדן נתונים, שימוש בדחיסת WebP ללא אובדן נתונים כדי לתעד את אופי המקור עם אובדן נתונים בדרך כלל יביא לקובץ גדול יותר. הבעיה הזו לא ייחודית ל-WebP, והיא יכולה להתרחש כשממירים מקור JPEG לפורמטים של WebP או PNG ללא אובדן נתונים, למשל.
- אם המקור הוא בפורמט עם אובדן נתונים ואתם מנסים לדחוס אותו כ-WebP עם אובדן נתונים בהגדרת איכות גבוהה יותר. לדוגמה, ניסיון להמיר קובץ JPEG ששמור באיכות 80 לקובץ WebP באיכות 95 בדרך כלל יניב קובץ גדול יותר, גם אם שני הפורמטים הם פורמטים עם אובדן נתונים.
לרוב אי אפשר להעריך את איכות המקור, ולכן מומלץ להקטין את איכות היעד של WebP אם גודל הקובץ גדול באופן עקבי.
אפשרות נוספת היא לא להשתמש בהגדרת האיכות, ובמקום זאת לטרגט גודל קובץ נתון באמצעות האפשרות
-size
בכליcwebp
או ב-API המקביל. לדוגמה, יכול להיות שהגדרת טירגוט של 80% מגודל הקובץ המקורי תהיה יעילה יותר.
שימו לב שהמרה של מקור JPEG ל-WebP עם אובדן נתונים, או של מקור PNG ל-WebP ללא אובדן נתונים, לא צפויה להניב קובץ בגודל לא צפוי.
האם WebP תומך בתצוגה פרוגרסיבית או בתצוגה בפורמט Interlaced?
פורמט WebP לא מציע רענון פענוח הדרגתי או שזור כמו בפורמט JPEG או PNG. סביר להניח שהדבר יפעיל לחץ רב מדי על המעבד ועל הזיכרון של לקוח הפענוח, כי כל אירוע רענון כולל מעבר מלא דרך מערכת הביטול של הדחיסה.
בממוצע, פענוח של תמונה מסוג JPEG פרוגרסיבי שווה לפענוח של תמונה מסוג baseline שלוש פעמים.
לחלופין, WebP מציע פענוח מצטבר, שבו כל הבייטים הנכנסים הזמינים של זרם הביטים משמשים כדי לנסות ליצור שורה לדוגמה שניתן להציג בהקדם האפשרי. כך נחסכים זיכרון ומאמץ של המעבד (CPU) ושל צביעה מחדש בצד הלקוח, ומוצגים רמזים ויזואליים לגבי סטטוס ההורדה. התכונה של פענוח מצטבר זמינה דרך Advanced Decoding API.
איך משתמשים ב-libwebp Java bindings בפרויקט Android?
WebP כולל תמיכה בקישורי JNI לממשקי המקודד והפענוח הפשוטים בספרייה swig/
.
יצירת הספרייה ב-Eclipse:
- מוודאים שהתקנתם את התוסף ADT יחד עם כלי ה-NDK, ושנתיב ה-NDK מוגדר בצורה נכונה (העדפות > Android > NDK).
- יוצרים פרויקט חדש: קובץ > חדש > פרויקט > פרויקט אפליקציית Android.
- Clone או unpack libwebp לתיקייה בשם
jni
בפרויקט החדש. - תוסיף את
swig/libwebp_java_wrap.c
לרשימהLOCAL_SRC_FILES
. - לוחצים לחיצה ימנית על הפרויקט החדש ובוחרים באפשרות Android Tools (כלים ל-Android) > Add Native Support ... (הוספת תמיכה מקורית...) כדי לכלול את הספרייה ב-build.
פותחים את מאפייני הפרויקט ועוברים אל C/C++ Build (גרסת C/C++) > Behaviour (התנהגות). מוסיפים את
ENABLE_SHARED=1
לקטעBuild (Incremental build)
כדי ליצור את libwebp כספרייה משותפת.הערה הגדרת
NDK_TOOLCHAIN_VERSION=4.8
בדרך כלל תשפר את הביצועים של גרסאות 32 ביט.מוסיפים את
swig/libwebp.jar
לתיקיית הפרויקטlibs/
.יוצרים את הפרויקט. הפעולה הזו תיצור
libs/<target-arch>/libwebp.so
.משתמשים ב-
System.loadLibrary("webp")
כדי לטעון את הספרייה בזמן הריצה.
שימו לב שאפשר ליצור את הספרייה באופן ידני באמצעות ndk-build
וAndroid.mk
. במקרה כזה, אפשר להשתמש שוב בחלק מהשלבים שמתוארים למעלה.
איך משתמשים ב-libwebp עם C#?
אפשר ליצור את WebP כ-DLL שמייצא את libwebp API. אחר כך אפשר לייבא את הפונקציות האלה ב-C#.
יוצרים את libwebp.dll. הפעולה הזו תגדיר את WEBP_EXTERN בצורה נכונה כדי לייצא את הפונקציות של ה-API.
libwebp> nmake /f Makefile.vc CFG=release-dynamic
מוסיפים את libwebp.dll לפרויקט ומייבאים את הפונקציות הרצויות. הערה: אם משתמשים ב-simple API, צריך להפעיל את הפונקציה
WebPFree()
כדי לפנות את כל המאגרים שמוחזרים.[DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)] static extern int WebPEncodeBGRA(IntPtr rgba, int width, int height, int stride, float quality_factor, out IntPtr output); [DllImport("libwebp.dll", CallingConvention = CallingConvention.Cdecl)] static extern int WebPFree(IntPtr p); void Encode() { Bitmap source = new Bitmap("input.png"); BitmapData data = source.LockBits( new Rectangle(0, 0, source.Width, source.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); IntPtr webp_data; const int size = WebPEncodeBGRA(data.Scan0, source.Width, source.Height, data.Stride, 80, out webp_data); // ... WebPFree(webp_data); }
למה כדאי להשתמש ב-WebP עם אנימציה?
היתרונות של WebP מונפש לעומת GIF מונפש
פורמט WebP תומך בצבעי RGB 24 ביט עם ערוץ אלפא 8 ביט, לעומת צבעי 8 ביט ואלפא 1 ביט בפורמט GIF.
פורמט WebP תומך בדחיסה מסוג lossy ו-lossless. למעשה, באנימציה אחת יכולים להיות פריימים מסוג lossy ופריימים מסוג lossless. GIF תומך רק בדחיסה ללא אובדן נתונים. טכניקות הדחיסה מסוג lossy של WebP מתאימות במיוחד לתמונות מונפשות שנוצרו מסרטונים מהעולם האמיתי, מקור פופולרי יותר ויותר לתמונות מונפשות.
פורמט WebP דורש פחות בייטים מ-GIF1. קובצי GIF מונפשים שהומרו ל-WebP עם אובדן נתונים קטנים ב-64%, וקובצי WebP ללא אובדן נתונים קטנים ב-19%. ההיבט הזה חשוב במיוחד ברשתות סלולריות.
בנוכחות חיפוש, לוקח פחות זמן לפענח WebP. ב-Blink, גלילה או מעבר בין כרטיסיות יכולים להסתיר ולהציג תמונות, וכתוצאה מכך האנימציות מושהות ואז מתקדמות לנקודה אחרת. שימוש מוגזם במעבד שגורם להשמטת פריימים באנימציות יכול גם לדרוש מהמפענח לחפש קדימה באנימציה. בתרחישים האלה, אנימציית WebP צורכת פי 0.57 יותר זמן כולל של פענוח2 מאשר GIF, וכתוצאה מכך יש פחות תקלות במהלך הגלילה וההתאוששות מעליות פתאומיות בשימוש במעבד מהירה יותר. הסיבה לכך היא שני יתרונות של WebP על פני GIF:
בתמונות WebP מאוחסנים מטא-נתונים שקובעים אם כל פריים מכיל אלפא, כך שלא צריך לפענח את הפריים כדי לקבוע את זה. כך אפשר להסיק בצורה מדויקת יותר על אילו פריימים קודמים תלוי פרים נתון, וכך לצמצם את הפענוח המיותר של פריימים קודמים.
בדומה למקודד וידאו מודרני, מקודד WebP מוסיף היוריסטית מסגרות מפתח במרווחי זמן קבועים (מה שרוב מקודדי ה-GIF לא עושים). כך משפרים באופן משמעותי את החיפוש באנימציות ארוכות. כדי להקל על הוספת פריימים כאלה בלי להגדיל באופן משמעותי את גודל התמונה, ב-WebP נוסף דגל של'שיטת מיזוג' לכל פריים, בנוסף לשיטת הסרת הפריים שבה נעשה שימוש ב-GIF. כך אפשר לצייר פריים מרכזי כאילו כל התמונה נוקתה לצבע הרקע בלי לכפות על הפריים הקודם להיות בגודל מלא.
חסרונות של WebP מונפש בהשוואה ל-GIF מונפש
בלי חיפוש, פענוח של WebP בקו ישר דורש יותר משאבי CPU מאשר GIF. זמן הפענוח של WebP עם אובדן נתונים ארוך פי 2.2 מזה של GIF, וזמן הפענוח של WebP ללא אובדן נתונים ארוך פי 1.5 מזה של GIF.
התמיכה ב-WebP לא נפוצה כמו התמיכה ב-GIF, שהיא למעשה אוניברסלית.
הוספת תמיכה ב-WebP לדפדפנים מגדילה את טביעת הרגל של הקוד ואת השטח החשוף להתקפה. ב-Blink מדובר בכ-1,500 שורות קוד נוספות (כולל ספריית WebP demux ומפענח תמונות WebP בצד Blink). שימו לב: יכול להיות שהבעיה הזו תצטמצם בעתיד אם WebP ו-WebM ישתמשו באותו קוד פענוח, או אם היכולות של WebP ייכללו ב-WebM.
למה לא לתמוך ב-WebM ב-<img>
?
יכול להיות שיהיה הגיוני לתמוך בפורמטים של סרטונים בתוך התג <img>
. עם זאת, אם תעשו את זה עכשיו, במטרה ש-WebM ב-<img>
יוכל למלא את התפקיד המוצע של WebP מונפש, תהיה בעיה:
כשמפענחים פריים שמסתמך על פריים קודם, WebM דורש 50% יותר זיכרון מאשר WebP מונפש כדי להחזיק את המספר המינימלי של פריים קודם3.
התמיכה בקודק וידאו ובקונטיינר משתנה מאוד בין דפדפנים ומכשירים. כדי לאפשר המרה אוטומטית של תוכן (למשל, עבור שרתי proxy לחיסכון ברוחב פס), דפדפנים צריכים להוסיף כותרות Accept שמציינות אילו פורמטים של תגי תמונה הם תומכים בהם. יכול להיות שגם זה לא יספיק, כי סוגי MIME כמו video/webm או video/mpeg עדיין לא מציינים את התמיכה בקודק (למשל VP8 לעומת VP9). מצד שני, פורמט WebP קפוא למעשה, ואם ספקים שמשתמשים בו יסכימו להשתמש ב-WebP עם אנימציה, ההתנהגות של WebP בכל סוכני המשתמש תהיה עקבית. בנוסף, כותרת בקשת הקבלה image/webp כבר משמשת לציון תמיכה ב-WebP, ולכן לא נדרשים שינויים חדשים בכותרת בקשת הקבלה.
חבילת הווידאו של Chromium מותאמת להפעלה חלקה, והיא מניחה שרק סרטון אחד או שניים מוצגים בכל פעם. כתוצאה מכך, ההטמעה צורכת באופן אגרסיבי משאבי מערכת (שרשורים, זיכרון וכו') כדי למקסם את איכות ההפעלה. הטמעה כזו לא מתאימה להצגת הרבה סרטונים בו-זמנית, וצריך לתכנן אותה מחדש כדי שתתאים לשימוש בדפי אינטרנט עם הרבה תמונות.
בשלב הזה, WebM לא כולל את כל טכניקות הדחיסה של WebP. כתוצאה מכך, התמונה הזו נדחסת הרבה יותר טוב בפורמט WebP מאשר בפורמטים חלופיים:
1 בכל ההשוואות בין קובצי GIF מונפשים לבין קובצי WebP מונפשים, השתמשנו במאגר של כ-7,000 תמונות GIF מונפשות שנלקחו באופן אקראי מהאינטרנט. התמונות האלה הומרו ל-WebP עם אנימציה באמצעות הכלי gif2webp עם הגדרות ברירת מחדל (שנוצר מעץ המקור האחרון של libwebp נכון ל-10/08/2013). המספרים להשוואה הם הערכים הממוצעים של התמונות האלה.
2 זמני הפענוח חושבו באמצעות libwebp + ToT Blink העדכניים ביותר נכון ל-10/08/2013, באמצעות כלי השוואה. החישוב של 'זמן פענוח עם חיפוש' הוא 'פענוח של חמש המסגרות הראשונות, ניקוי של מטמון מאגר המסגרות, פענוח של חמש המסגרות הבאות וכן הלאה'.
3 WebM שומר 4 פריימים של YUV reference בזיכרון, וכל פריימ
שומר (width+96)*(height+96) פיקסלים. בפורמט YUV 4:2:0, אנחנו צריכים 4 בייטים לכל 6 פיקסלים (או 3/2 בייטים לכל פיקסל). לכן, מסגרות ההפניה האלה משתמשות בזיכרון של 4*3/2*(width+96)*(height+96)
בייטים. לעומת זאת, כדי להשתמש ב-WebP, צריך רק את הפריים הקודם (ב-RGBA), שדורש 4*width*height
בייט של זיכרון.
4 כדי להציג WebP עם אנימציה צריך גרסה 32 ומעלה של Google Chrome