Ban đầu, Google phát triển WebP dưới dạng một định dạng hình ảnh có tổn hao để thay thế JPEG – một định dạng có thể tạo ra các tệp nhỏ hơn so với tệp hình ảnh có chất lượng tương đương được mã hoá dưới dạng JPEG. Các bản cập nhật sau này cho định dạng này đã giới thiệu lựa chọn nén không mất dữ liệu, độ trong suốt của kênh alpha giống như PNG và ảnh động giống GIF – tất cả đều có thể được sử dụng cùng với tính năng nén có tổn hao kiểu JPEG. WebP là một định dạng linh hoạt không tưởng.
Thuật toán nén có tổn hao của WebP dựa trên phương thức mà bộ mã hoá và giải mã video VP8 dùng để nén khung hình chính trong video. Ở cấp độ cao, phương pháp mã hoá này tương tự như phương thức mã hoá JPEG: WebP hoạt động theo phương thức "khối" thay vì từng pixel riêng lẻ, đồng thời có sự phân chia tương tự giữa độ chói và sắc độ. Các khối luma của WebP có kích thước 16x16, còn các khối chroma là 8x8, và các "macroblock" đó được chia nhỏ hơn thành các khối con 4x4.
Trong đó, WebP khác biệt hoàn toàn với JPEG ở hai tính năng: "dự đoán khối" và "lượng tử hoá khối thích ứng".
Chặn dự đoán
Dự đoán khối là quá trình dự đoán nội dung của từng khối sắc độ và độ chói dựa trên giá trị của các khối xung quanh, cụ thể là các khối phía trên và bên trái của khối hiện tại. Như bạn có thể tưởng tượng, các thuật toán thực hiện công việc này khá phức tạp, nhưng hãy diễn đạt bằng ngôn ngữ đơn giản: "nếu có màu xanh dương ở phía trên khối hiện tại và có màu xanh lam ở bên trái của khối hiện tại, giả sử khối này có màu xanh dương".
Trên thực tế, cả PNG và JPEG cũng thực hiện dự đoán này ở một mức độ nào đó. Tuy nhiên, WebP có điểm độc đáo ở chỗ lấy mẫu dữ liệu của các khối xung quanh, sau đó cố gắng điền khối hiện tại bằng một số "chế độ dự đoán", cố gắng "vẽ" phần bị thiếu của hình ảnh một cách hiệu quả. Sau đó, kết quả do mỗi chế độ dự đoán cung cấp sẽ được so sánh với dữ liệu hình ảnh thực và kết quả dự đoán khớp gần nhất sẽ được chọn.
![Sơ đồ về các phương thức dự đoán khối của WebP.](https://web.dev/static/learn/images/webp/image/a-diagram-webps-various-05ac7c823c177.png?authuser=5&hl=vi)
Tất nhiên, ngay cả kết quả dự đoán khớp gần nhất cũng sẽ không hoàn toàn chính xác, do đó, sự khác biệt giữa giá trị dự đoán và giá trị thực tế của khối đó được mã hoá trong tệp. Khi giải mã hình ảnh, công cụ kết xuất hình ảnh sử dụng cùng một dữ liệu để áp dụng cùng một logic dự đoán, dẫn đến các giá trị dự đoán giống nhau cho mỗi khối. Sau đó, sự khác biệt giữa thông tin dự đoán và hình ảnh dự kiến được mã hoá trong tệp sẽ được áp dụng trên các dự đoán—tương tự như cách cam kết Git đại diện cho một bản vá vi phân được áp dụng trên tệp cục bộ, thay vì một bản sao hoàn toàn mới của tệp.
Để minh hoạ: thay vì tìm hiểu sâu về phép toán phức tạp có liên quan đến thuật toán dự đoán thực tế, chúng tôi sẽ phát minh ra phương thức mã hoá giống như WebP với một chế độ dự đoán duy nhất và sử dụng chế độ này để chuyển tiếp hiệu quả lưới số theo cách chúng tôi đã làm với các định dạng cũ. Thuật toán của chúng tôi có một chế độ dự đoán duy nhất mà chúng tôi gọi là "chế độ dự đoán 1". Giá trị của mỗi khối là tổng giá trị của các khối phía trên và ở bên trái, bắt đầu bằng 1.
Bây giờ, giả sử chúng ta đang bắt đầu với dữ liệu hình ảnh thực sau:
111151111
122456389
Sử dụng mô hình dự đoán để xác định nội dung của lưới 2x9, chúng ta sẽ nhận được kết quả sau:
111111111
123456789
Dữ liệu của chúng tôi rất phù hợp với thuật toán dự đoán mà chúng tôi đã phát minh. Dữ liệu dự đoán gần giống với dữ liệu thực của chúng tôi. Tất nhiên, không hoàn toàn phù hợp — dữ liệu thực tế có một vài khối khác với dữ liệu dự đoán. Vì vậy, phương thức mã hoá mà chúng tôi gửi không chỉ bao gồm phương thức dự đoán mà còn bao gồm điểm khác biệt giữa các khối cần khác với giá trị dự đoán:
_ _ _ _ +4 _ _ _ _
_ _ -1 _ _ _ -4 _ _
Đặt cùng một loại ngôn ngữ đơn giản với một số phương thức mã hoá định dạng cũ mà chúng ta đã thảo luận:
Lưới 2x9 sử dụng chế độ dự đoán 1. +4 đến 1x5, -1 đến 2x3, -4 đến 2x7.
Kết quả cuối cùng là một tệp được mã hoá hiệu quả đến không ngờ.
Số lượng khối thích ứng
Nén JPEG là một hoạt động tổng quát, áp dụng cùng một mức lượng tử hoá cho mọi khối trong ảnh. Trong một hình ảnh có bố cục đồng nhất, điều đó chắc chắn có ý nghĩa, nhưng ảnh trong thế giới thực không đồng nhất so với thế giới xung quanh chúng ta. Trong thực tế, điều này có nghĩa là chế độ nén ảnh JPEG của chúng tôi không được xác định bằng các chi tiết tần số cao (trong đó độ nén JPEG vượt trội) mà được xác định bởi những phần hình ảnh nơi các cấu phần phần mềm nén có nhiều khả năng xuất hiện nhất.
Như bạn có thể thấy trong ví dụ phóng đại này, cánh của quốc vương ở phía trước trông tương đối sắc nét — hơi sần sùi khi so sánh với bản gốc có độ phân giải cao, nhưng chắc chắn không đáng chú ý nếu không có bản gốc để so sánh với bản gốc. Tương tự như vậy, sự phát quang chi tiết của cỏ sữa và lá ở phía trước — bạn và tôi có thể thấy dấu vết của cấu phần nén bằng đôi mắt đã qua huấn luyện của chúng ta, nhưng ngay cả khi độ nén được quay số vượt quá mức hợp lý thì mọi thứ ở nền trước vẫn trông khá sắc nét. Thông tin tần suất thấp ở phía trên cùng bên trái của ảnh (nền xanh lục mờ ảo của những chiếc lá) trông khủng khiếp. Ngay cả người xem chưa qua đào tạo cũng có thể nhận thấy ngay vấn đề về chất lượng — các sắc chuyển màu tinh tế trên nền được làm tròn xuống thành các khối màu đồng nhất, lởm chởm.
Để tránh điều này, WebP áp dụng một phương pháp thích ứng để lượng tử hoá: một hình ảnh được chia thành tối đa 4 phân đoạn có hình ảnh tương tự nhau và các thông số nén cho những phân đoạn đó được điều chỉnh một cách độc lập. Sử dụng cùng một phương thức nén quá cỡ với WebP:
Kích thước của cả hai tệp hình ảnh này tương đương nhau. Chất lượng tương đương khi chúng ta xem xét cánh của vua — bạn có thể nhận thấy một vài khác biệt nhỏ trong kết quả cuối cùng nếu bạn nhìn rất gần, nhưng không có sự khác biệt thực sự về chất lượng tổng thể. Trong WebP, những bông hoa của cỏ sữa chỉ sắc nét hơn một chút – một lần nữa, có khả năng không đủ để đáng chú ý trừ khi bạn so sánh hai loại cạnh nhau và thực sự tìm kiếm sự khác biệt về chất lượng. Bối cảnh là một câu chuyện hoàn toàn khác: hầu như không để lại dấu vết của các cấu phần phần mềm rõ ràng của JPEG. WebP cung cấp cho chúng tôi cùng một kích thước tệp, nhưng hình ảnh có chất lượng cao hơn nhiều – cần cung cấp hoặc bao gồm một vài chi tiết nhỏ mà hệ thống thị giác của chúng tôi sẽ không thể phát hiện ra nếu chúng tôi không so sánh hai hệ thống này một cách chặt chẽ.
Sử dụng WebP
Nội dung bên trong của WebP có thể phức tạp hơn nhiều so với phương thức mã hoá JPEG, nhưng cũng đơn giản hơn để phục vụ cho công việc hằng ngày của chúng ta: tất cả độ phức tạp của việc mã hoá WebP đều được chuẩn hoá xoay quanh một giá trị "chất lượng" duy nhất, được biểu thị từ 0 đến 100, giống như JPEG. Và một lần nữa, điều đó không có nghĩa là bạn bị giới hạn ở một chế độ cài đặt "chất lượng" bao quát. Bạn có thể và nên cải tiến tất cả thông tin chi tiết về phương thức mã hoá WebP để hiểu rõ hơn về mức độ ảnh hưởng của các chế độ cài đặt thường hiển thị này đến kích thước và chất lượng tệp.
Google cung cấp một bộ mã hoá dòng lệnh cwebp
cho phép bạn chuyển đổi hoặc nén từng tệp hoặc toàn bộ thư mục của hình ảnh:
$ 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 |
Và nếu bạn không quan tâm đến dòng lệnh, thì Squoosh cũng sẽ phân phát cho chúng tôi cũng như để mã hoá WebP. Tính năng này cho phép chúng tôi so sánh song song giữa các phương thức mã hoá, chế độ cài đặt, mức chất lượng, cũng như sự khác biệt về kích thước tệp so với phương thức mã hoá JPEG.