WebP là gì? Tại sao tôi nên sử dụng tính năng này?
WebP là một phương pháp nén có tổn hao và không tổn hao mà bạn có thể sử dụng cho nhiều loại hình ảnh chụp, hình ảnh trong suốt và hình ảnh đồ hoạ trên web. Mức độ nén có tổn hao có thể điều chỉnh để người dùng có thể chọn sự đánh đổi giữa kích thước tệp và chất lượng hình ảnh. WebP thường đạt mức nén trung bình cao hơn 30% so với JPEG và JPEG 2000 mà không làm giảm chất lượng hình ảnh (xem Nghiên cứu so sánh).
Định dạng WebP về cơ bản nhằm mục đích tạo ra những hình ảnh nhỏ hơn và đẹp hơn, có thể giúp trang web chạy nhanh hơn.
Những trình duyệt web nào hỗ trợ sẵn định dạng WebP?
Quản trị viên web muốn cải thiện hiệu suất trang web có thể dễ dàng tạo các lựa chọn thay thế WebP được tối ưu hoá cho hình ảnh hiện tại và phân phát các lựa chọn thay thế đó một cách có mục tiêu cho những trình duyệt hỗ trợ WebP.
- Hỗ trợ WebP có tổn hao
- Google Chrome (máy tính) phiên bản 17 trở lên
- Google Chrome cho Android phiên bản 25 trở lên
- Microsoft Edge 18 trở lên
- Firefox 65 trở lên
- Opera 11.10 trở lên
- Trình duyệt web gốc, Android 4.0 trở lên (ICS)
- Safari 14 trở lên (iOS 14 trở lên, macOS Big Sur trở lên)
- Hỗ trợ WebP có tổn thất, không tổn thất và alpha
- Google Chrome (máy tính) phiên bản 23 trở lên
- Google Chrome cho Android phiên bản 25 trở lên
- Microsoft Edge 18 trở lên
- Firefox 65 trở lên
- Opera 12.10 trở lên
- Trình duyệt web gốc, Android 4.2 trở lên (JB-MR1)
- Pale Moon 26 trở lên
- Safari 14 trở lên (iOS 14 trở lên, macOS Big Sur trở lên)
- Hỗ trợ ảnh động WebP
- Google Chrome (máy tính và Android) phiên bản 32 trở lên
- Microsoft Edge 18 trở lên
- Firefox 65 trở lên
- Opera 19 trở lên
- Safari 14 trở lên (iOS 14 trở lên, macOS Big Sur trở lên)
Xem thêm:
Làm cách nào để phát hiện khả năng hỗ trợ WebP của trình duyệt?
Bạn chỉ nên phân phát hình ảnh WebP cho những ứng dụng có thể hiển thị hình ảnh này đúng cách và quay lại các định dạng cũ cho những ứng dụng không thể. Rất may là có một số kỹ thuật để phát hiện khả năng hỗ trợ WebP, cả ở phía máy khách và phía máy chủ. Một số nhà cung cấp CDN cung cấp tính năng phát hiện khả năng hỗ trợ WebP trong dịch vụ của họ.
Thương lượng nội dung phía máy chủ thông qua tiêu đề Chấp nhận
Các ứng dụng web thường gửi tiêu đề yêu cầu "Accept" (Chấp nhận), cho biết định dạng nội dung mà chúng sẵn sàng chấp nhận trong phản hồi. Nếu trình duyệt cho biết trước rằng trình duyệt sẽ "chấp nhận" định dạng image/webp, máy chủ web sẽ biết rằng trình duyệt có thể gửi hình ảnh WebP một cách an toàn, giúp đơn giản hoá đáng kể quá trình thương lượng nội dung. Hãy truy cập vào các đường liên kết sau để biết thêm thông tin.
- Triển khai các định dạng hình ảnh mới trên web
- Phân phát hình ảnh WebP cho khách truy cập bằng cách sử dụng các phần tử HTML
Modernizr
Modernizr là một thư viện JavaScript giúp phát hiện một cách thuận tiện khả năng hỗ trợ tính năng HTML5 và CSS3 trong trình duyệt web. Tìm các thuộc tính Modernizr.webp, Modernizr.webp.lossless, Modernizr.webp.alpha và Modernizr.webp.animation.
Phần tử <picture>
HTML5
HTML5 hỗ trợ phần tử <picture>
, cho phép bạn liệt kê nhiều mục tiêu hình ảnh thay thế theo thứ tự ưu tiên, sao cho một ứng dụng sẽ yêu cầu hình ảnh đề xuất đầu tiên mà ứng dụng đó có thể hiển thị đúng cách. Xem cuộc thảo luận này trên HTML5 Rocks. Phần tử <picture>
luôn được nhiều trình duyệt hỗ trợ.
Trong JavaScript của riêng bạn
Một phương pháp phát hiện khác là cố gắng giải mã một hình ảnh WebP rất nhỏ sử dụng một tính năng cụ thể và kiểm tra xem có thành công hay không. Ví dụ:
// 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];
}
Xin lưu ý rằng quá trình tải hình ảnh không chặn và không đồng bộ. Điều này có nghĩa là bạn nên đặt mọi mã phụ thuộc vào khả năng hỗ trợ WebP trong hàm gọi lại.
Tại sao Google phát hành WebP dưới dạng nguồn mở?
Chúng tôi tin tưởng sâu sắc vào tầm quan trọng của mô hình nguồn mở. Vì WebP là nguồn mở, nên bất kỳ ai cũng có thể làm việc với định dạng này và đề xuất các điểm cải tiến. Với ý kiến đóng góp và đề xuất của bạn, chúng tôi tin rằng WebP sẽ ngày càng hữu ích hơn với tư cách là một định dạng đồ hoạ.
Làm cách nào để chuyển đổi tệp hình ảnh cá nhân sang WebP?
Bạn có thể sử dụng tiện ích dòng lệnh WebP để chuyển đổi các tệp hình ảnh cá nhân sang định dạng WebP. Hãy xem phần Sử dụng WebP để biết thêm thông tin.
Nếu có nhiều hình ảnh cần chuyển đổi, bạn có thể sử dụng shell của nền tảng để đơn giản hoá thao tác. Ví dụ: để chuyển đổi tất cả các tệp jpeg trong một thư mục, hãy thử làm như sau:
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
Làm cách nào để tự đánh giá chất lượng hình ảnh WebP?
Hiện tại, bạn có thể xem các tệp WebP bằng cách chuyển đổi chúng sang một định dạng phổ biến sử dụng phương pháp nén không tổn hao, chẳng hạn như PNG, rồi xem các tệp PNG trong bất kỳ trình duyệt hoặc trình xem hình ảnh nào. Để biết nhanh về chất lượng WebP, hãy xem Thư viện trên trang web này để so sánh ảnh cạnh nhau.
Làm cách nào để lấy mã nguồn?
Mã của trình chuyển đổi có trong phần tải xuống của trang dự án nguồn mở WebP. Mã cho bộ giải mã đơn giản và quy cách VP8 nằm trên trang web WebM. Hãy xem trang Vùng chứa RIFF để biết quy cách vùng chứa.
Kích thước tối đa của hình ảnh WebP là bao nhiêu?
WebP tương thích với luồng bit VP8 và sử dụng 14 bit cho chiều rộng và chiều cao. Kích thước pixel tối đa của hình ảnh WebP là 16383 x 16383.
Định dạng WebP hỗ trợ những không gian màu nào?
Tương tự như luồng bit VP8, WebP có tổn hao chỉ hoạt động với định dạng hình ảnh Y'CbCr 4:2:0 8 bit (thường được gọi là YUV420). Vui lòng tham khảo Phần 2, "Tổng quan về định dạng" của RFC 6386, Hướng dẫn giải mã và định dạng dữ liệu VP8 để biết thêm thông tin chi tiết.
WebP không mất dữ liệu chỉ hoạt động với định dạng RGBA. Xem quy cách Luồng bit không mất dữ liệu WebP.
Tại sao tệp WebP không mất dữ liệu của tôi lại khác với tệp gốc?
Các hàm Simple Encoding API (WebPEncodeLosslessRGB()
, WebPEncodeLosslessBGR()
, WebPEncodeLosslessRGBA()
, WebPEncodeLosslessBGRA()
) sử dụng chế độ cài đặt mặc định của thư viện. Đối với chế độ nén không mất dữ liệu, điều này có nghĩa là chế độ "chính xác" bị tắt. Giá trị RGB ở các vùng hoàn toàn trong suốt (tức là các vùng có giá trị alpha bằng 0
) sẽ được sửa đổi để cải thiện khả năng nén. Để tránh điều này, hãy dùng WebPEncode()
và đặt WebPConfig::exact
thành 1
. Hãy xem tài liệu về API mã hoá nâng cao.
Hình ảnh WebP có thể lớn hơn hình ảnh nguồn không?
Có, thường là khi chuyển đổi từ định dạng có tổn hao sang định dạng WebP không tổn hao hoặc ngược lại. Điều này chủ yếu là do sự khác biệt về không gian màu (YUV420 so với ARGB) và quá trình chuyển đổi giữa các không gian màu này.
Có 3 trường hợp điển hình:
- Nếu hình ảnh nguồn ở định dạng ARGB không mất dữ liệu, thì việc giảm độ phân giải không gian xuống YUV420 sẽ tạo ra các màu mới khó nén hơn so với màu gốc. Tình huống này thường xảy ra khi nguồn ở định dạng PNG có ít màu: việc chuyển đổi sang WebP có tổn hao (hoặc tương tự như JPEG có tổn hao) có thể dẫn đến kích thước tệp lớn hơn.
- Nếu nguồn ở định dạng hao tổn, việc sử dụng phương thức nén WebP không hao tổn để ghi lại bản chất hao tổn của nguồn thường sẽ dẫn đến một tệp lớn hơn. Điều này không chỉ xảy ra với WebP mà còn có thể xảy ra khi bạn chuyển đổi một nguồn JPEG sang định dạng WebP hoặc PNG không suy hao, chẳng hạn.
- Nếu nguồn ở định dạng có tổn hao và bạn đang cố gắng nén nguồn đó dưới dạng WebP có tổn hao với chế độ cài đặt chất lượng cao hơn. Ví dụ: việc cố gắng chuyển đổi một tệp JPEG được lưu ở chất lượng 80 thành một tệp WebP có chất lượng 95 thường sẽ dẫn đến một tệp lớn hơn, ngay cả khi cả hai định dạng đều bị mất dữ liệu.
Thường thì bạn không thể đánh giá chất lượng của nguồn, vì vậy, bạn nên giảm chất lượng WebP mục tiêu nếu kích thước tệp luôn lớn hơn.
Một khả năng khác là tránh sử dụng chế độ cài đặt chất lượng và thay vào đó, hãy nhắm đến một kích thước tệp nhất định bằng cách sử dụng lựa chọn
-size
trong công cụcwebp
hoặc API tương đương. Ví dụ: việc nhắm đến 80% kích thước tệp gốc có thể mang lại kết quả ổn định hơn.
Xin lưu ý rằng việc chuyển đổi nguồn JPEG sang WebP suy hao hoặc nguồn PNG sang WebP không suy hao không dễ gặp phải những trường hợp bất ngờ về kích thước tệp như vậy.
WebP có hỗ trợ hiển thị xen kẽ hoặc liên tục không?
WebP không cung cấp tính năng làm mới giải mã xen kẽ hoặc tăng dần theo kiểu JPEG hoặc PNG. Điều này có thể gây quá nhiều áp lực lên CPU và bộ nhớ của ứng dụng giải mã vì mỗi sự kiện làm mới đều liên quan đến một lượt truyền đầy đủ thông qua hệ thống giải nén.
Trung bình, việc giải mã một hình ảnh JPEG tăng tiến tương đương với việc giải mã hình ảnh cơ sở 3 lần.
Ngoài ra, WebP còn cung cấp tính năng giải mã tăng dần, trong đó tất cả các byte đến hiện có của luồng bit đều được dùng để cố gắng tạo ra một hàng mẫu có thể hiển thị trong thời gian sớm nhất có thể. Điều này giúp tiết kiệm bộ nhớ, CPU và công sức vẽ lại trên máy khách, đồng thời cung cấp tín hiệu trực quan về trạng thái tải xuống. Bạn có thể sử dụng tính năng giải mã gia tăng thông qua Advanced Decoding API.
Làm cách nào để sử dụng các liên kết Java libwebp trong dự án Android của tôi?
WebP hỗ trợ các liên kết JNI với các giao diện bộ mã hoá và bộ giải mã đơn giản trong thư mục swig/
.
Tạo thư viện trong Eclipse:
- Đảm bảo bạn đã cài đặt trình bổ trợ ADT cùng với các công cụ NDK và đường dẫn NDK được đặt chính xác (Preferences (Lựa chọn ưu tiên) > Android > NDK).
- Tạo một dự án mới: File > New > Project > Android Application Project (Tệp > Mới > Dự án > Dự án ứng dụng Android).
- Nhân bản hoặc giải nén libwebp vào một thư mục có tên là
jni
trong dự án mới. - Thêm
swig/libwebp_java_wrap.c
vào danh sáchLOCAL_SRC_FILES
. - Nhấp chuột phải vào dự án mới rồi chọn Android Tools (Các công cụ Android) > Add Native Support ... (Thêm tính năng hỗ trợ mã gốc...) để đưa thư viện vào bản dựng.
Mở thuộc tính dự án rồi chuyển đến C/C++ Build (Bản dựng C/C++) > Behaviour (Hành vi). Thêm
ENABLE_SHARED=1
vào phầnBuild (Incremental build)
để tạo libwebp dưới dạng thư viện dùng chung.Lưu ý: Việc đặt
NDK_TOOLCHAIN_VERSION=4.8
thường sẽ cải thiện hiệu suất bản dựng 32 bit.Thêm
swig/libwebp.jar
vào thư mục dự ánlibs/
.Tạo dự án. Thao tác này sẽ tạo ra
libs/<target-arch>/libwebp.so
.Sử dụng
System.loadLibrary("webp")
để tải thư viện trong thời gian chạy.
Xin lưu ý rằng bạn có thể tạo thư viện theo cách thủ công bằng ndk-build
và Android.mk
đi kèm. Trong trường hợp đó, bạn có thể sử dụng lại một số bước được mô tả ở trên.
Làm cách nào để sử dụng libwebp với C#?
WebP có thể được tạo dưới dạng một DLL xuất API libwebp. Sau đó, bạn có thể nhập các hàm này trong C#.
Tạo libwebp.dll. Thao tác này sẽ đặt WEBP_EXTERN đúng cách để xuất các hàm API.
libwebp> nmake /f Makefile.vc CFG=release-dynamic
Thêm libwebp.dll vào dự án của bạn và nhập các hàm mong muốn. Lưu ý: nếu sử dụng API đơn giản, bạn nên gọi
WebPFree()
để giải phóng mọi vùng đệm được trả về.[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); }
Tại sao tôi nên sử dụng WebP động?
Ưu điểm của WebP động so với GIF động
WebP hỗ trợ màu RGB 24 bit với kênh alpha 8 bit, so với màu 8 bit và alpha 1 bit của GIF.
WebP hỗ trợ cả phương pháp nén có tổn hao và không tổn hao; trên thực tế, một ảnh động có thể kết hợp cả khung hình có tổn hao và không tổn hao. GIF chỉ hỗ trợ chế độ nén không mất dữ liệu. Các kỹ thuật nén có tổn hao của WebP rất phù hợp với hình ảnh động được tạo từ video trong thế giới thực, một nguồn hình ảnh động ngày càng phổ biến.
WebP yêu cầu ít byte hơn GIF1. Ảnh GIF động được chuyển đổi sang định dạng WebP suy hao có kích thước nhỏ hơn 64%, trong khi ảnh WebP không suy hao có kích thước nhỏ hơn 19%. Điều này đặc biệt quan trọng trên mạng di động.
WebP mất ít thời gian hơn để giải mã khi có thao tác tìm kiếm. Trong Blink, thao tác cuộn hoặc thay đổi thẻ có thể ẩn và hiện hình ảnh, dẫn đến việc ảnh động bị tạm dừng rồi chuyển tiếp đến một điểm khác. Mức sử dụng CPU quá mức dẫn đến việc ảnh động bị giảm khung hình cũng có thể yêu cầu bộ giải mã tìm kiếm về phía trước trong ảnh động. Trong những trường hợp này, WebP động mất tổng thời gian giải mã gấp 0,57 lần2 so với GIF, dẫn đến ít hiện tượng giật hơn trong khi cuộn và phục hồi nhanh hơn sau khi mức sử dụng CPU tăng đột biến. Điều này là do WebP có 2 ưu điểm so với GIF:
Hình ảnh WebP lưu trữ siêu dữ liệu về việc mỗi khung hình có chứa alpha hay không, giúp bạn không cần phải giải mã khung hình để xác định điều này. Điều này dẫn đến suy luận chính xác hơn về những khung hình trước đó mà một khung hình nhất định phụ thuộc vào, từ đó giảm việc giải mã không cần thiết các khung hình trước đó.
Tương tự như một bộ mã hoá video hiện đại, bộ mã hoá WebP sẽ thêm các khung hình chính theo kinh nghiệm sau những khoảng thời gian đều đặn (hầu hết các bộ mã hoá GIF đều không làm như vậy). Điều này giúp cải thiện đáng kể khả năng tìm kiếm trong các ảnh động dài. Để tạo điều kiện thuận lợi cho việc chèn các khung hình như vậy mà không làm tăng đáng kể kích thước hình ảnh, WebP sẽ thêm một cờ "phương thức kết hợp" cho từng khung hình ngoài phương thức loại bỏ khung hình mà GIF sử dụng. Điều này cho phép một khung hình chính vẽ như thể toàn bộ hình ảnh đã được xoá về màu nền mà không buộc khung hình trước đó phải có kích thước đầy đủ.
Nhược điểm của WebP động so với GIF động
Nếu không có thao tác tìm kiếm, việc giải mã WebP theo đường thẳng sẽ tốn nhiều CPU hơn so với GIF. WebP tổn hao mất thời gian giải mã gấp 2,2 lần so với GIF, trong khi WebP không tổn hao mất thời gian giải mã gấp 1,5 lần.
Khả năng hỗ trợ WebP không phổ biến bằng khả năng hỗ trợ GIF (hầu như là phổ biến).
Việc thêm tính năng hỗ trợ WebP vào trình duyệt sẽ làm tăng dấu vết mã và bề mặt tấn công. Trong Blink, đây là khoảng 1.500 dòng mã bổ sung (bao gồm cả thư viện demux WebP và trình giải mã hình ảnh WebP phía Blink). Xin lưu ý rằng vấn đề này có thể giảm bớt trong tương lai nếu WebP và WebM dùng chung nhiều mã giải mã phổ biến hơn hoặc nếu các chức năng của WebP được đưa vào WebM.
Tại sao không chỉ hỗ trợ WebM trong <img>
?
Về lâu dài, bạn nên hỗ trợ các định dạng video bên trong thẻ <img>
. Tuy nhiên, việc làm như vậy hiện tại, với ý định rằng WebM trong <img>
có thể đảm nhận vai trò được đề xuất của WebP động, là một vấn đề:
Khi giải mã một khung hình dựa trên các khung hình trước đó, WebM cần thêm 50% bộ nhớ so với WebP động để giữ số lượng khung hình tối thiểu trước đó3.
Khả năng hỗ trợ codec và vùng chứa video rất khác nhau giữa các trình duyệt và thiết bị. Để tạo điều kiện cho việc chuyển mã nội dung tự động (ví dụ: đối với các proxy tiết kiệm băng thông), trình duyệt sẽ cần thêm tiêu đề chấp nhận cho biết những định dạng mà thẻ hình ảnh của chúng hỗ trợ. Ngay cả điều này cũng có thể không đủ, vì các loại MIME như "video/webm" hoặc "video/mpeg" vẫn không cho biết khả năng hỗ trợ codec (ví dụ: VP8 so với VP9). Mặt khác, định dạng WebP đã được cố định một cách hiệu quả và nếu các nhà cung cấp phân phối định dạng này đồng ý phân phối WebP động, thì hành vi của WebP trên tất cả các UA phải nhất quán; và vì tiêu đề chấp nhận "image/webp" đã được dùng để cho biết khả năng hỗ trợ WebP, nên không cần thay đổi tiêu đề chấp nhận mới.
Ngăn xếp video Chromium được tối ưu hoá để phát mượt mà và giả định rằng chỉ có một hoặc hai video phát cùng một lúc. Do đó, quá trình triển khai sẽ tiêu thụ nhiều tài nguyên hệ thống (luồng, bộ nhớ, v.v.) để tối đa hoá chất lượng phát. Việc triển khai như vậy không phù hợp với nhiều video đồng thời và cần được thiết kế lại để phù hợp với việc sử dụng các trang web có nhiều hình ảnh.
WebM hiện không kết hợp tất cả các kỹ thuật nén của WebP. Do đó, hình ảnh này nén tốt hơn đáng kể bằng WebP so với các lựa chọn thay thế:
1 Đối với tất cả các so sánh giữa ảnh GIF động và ảnh WebP động, chúng tôi đã sử dụng một tập hợp gồm khoảng 7.000 ảnh GIF động được lấy ngẫu nhiên trên web. Những hình ảnh này được chuyển đổi sang WebP động bằng công cụ "gif2webp" bằng cách sử dụng các chế độ cài đặt mặc định (được tạo từ cây nguồn libwebp mới nhất tính đến ngày 8/10/2013). Các con số so sánh là giá trị trung bình của những hình ảnh này.
2 Thời gian giải mã được tính bằng libwebp mới nhất + ToT Blink kể từ ngày 8/10/2013 bằng công cụ đo điểm chuẩn. "Thời gian giải mã khi tìm kiếm" được tính là "Giải mã 5 khung hình đầu tiên, xoá bộ nhớ đệm khung hình, giải mã 5 khung hình tiếp theo, v.v.".
3 WebM giữ 4 khung hình tham chiếu YUV trong bộ nhớ, trong đó mỗi khung hình lưu trữ (chiều rộng+96)*(chiều cao+96) pixel. Đối với YUV 4:2:0, chúng ta cần 4 byte cho mỗi 6 pixel (hoặc 3/2 byte cho mỗi pixel). Vì vậy, các khung tham chiếu này sử dụng 4*3/2*(width+96)*(height+96)
byte bộ nhớ. Mặt khác, WebP chỉ cần có khung hình trước đó (ở định dạng RGBA), tức là 4*width*height
byte bộ nhớ.
4 Để hiển thị WebP động, bạn cần có Google Chrome phiên bản 32 trở lên