Giới thiệu
WebP là một định dạng hình ảnh sử dụng (i) phương thức mã hoá khung hình chính VP8 để nén dữ liệu hình ảnh theo cách có tổn hao hoặc (ii) phương thức mã hoá không tổn hao WebP. Các lược đồ mã hoá này sẽ giúp hình ảnh hiệu quả hơn so với các định dạng cũ, chẳng hạn như JPEG, GIF và PNG. Nó được tối ưu hoá để chuyển hình ảnh nhanh qua mạng (ví dụ: đối với trang web). Định dạng WebP có tính năng đồng nhất (hồ sơ màu, siêu dữ liệu, ảnh động, v.v.) với các định dạng khác. Tài liệu này mô tả cấu trúc của tệp WebP.
Vùng chứa WebP (tức là vùng chứa RIFF cho WebP) cho phép hỗ trợ tính năng ngoài trường hợp sử dụng cơ bản của WebP (tức là tệp chứa một hình ảnh duy nhất được mã hoá dưới dạng khung hình chính VP8). Vùng chứa WebP cung cấp thêm tính năng hỗ trợ cho những nội dung sau:
Nén không tổn hao: Bạn có thể nén hình ảnh không tổn hao bằng Định dạng WebP không tổn hao.
Siêu dữ liệu: Hình ảnh có thể có siêu dữ liệu được lưu trữ ở định dạng Tệp hình ảnh có thể trao đổi (Exif) hoặc Nền tảng siêu dữ liệu mở rộng (XMP).
Độ trong suốt: Hình ảnh có thể có độ trong suốt, tức là kênh alpha.
Hồ sơ màu: Hình ảnh có thể có hồ sơ ICC được nhúng như mô tả của International Color Consortium (Liên minh màu sắc quốc tế).
Ảnh động: Một hình ảnh có thể có nhiều khung hình với các khoảng tạm dừng giữa các khung hình, tạo thành ảnh động.
Đặt tên
Bạn NÊN sử dụng các loại sau đây khi tham chiếu đến vùng chứa WebP:
Tên định dạng vùng chứa | WebP |
Phần mở rộng tên tệp | .webp |
Loại MIME | image/webp |
Giá trị nhận dạng loại thống nhất | org.webmproject.webp |
Thuật ngữ và kiến thức cơ bản
Các từ khoá "PHẢI", "KHÔNG ĐƯỢC", "BẮT BUỘC", "SẼ", "KHÔNG SẼ", "NÊN", "KHÔNG NÊN", "CÓ THỂ" và "KHÔNG BẮT BUỘC" trong tài liệu này sẽ được diễn giải như mô tả trong BCP 14 RFC 2119 RFC 8174 khi và chỉ khi các từ khoá này xuất hiện ở dạng viết hoa toàn bộ, như minh hoạ ở đây.
Tệp WebP chứa một hình ảnh tĩnh (tức là một ma trận pixel được mã hoá) hoặc một ảnh động. Tệp này cũng có thể chứa thông tin về độ trong suốt, hồ sơ màu và siêu dữ liệu (không bắt buộc). Chúng ta gọi ma trận pixel là canvas của hình ảnh.
Việc đánh số bit trong sơ đồ phân đoạn bắt đầu từ 0
cho bit có nghĩa nhất ('MSB 0'), như mô tả trong RFC 1166.
Dưới đây là các thuật ngữ bổ sung được sử dụng trong toàn bộ tài liệu này:
- Đọc/Ghi
- Mã đọc tệp WebP được gọi là trình đọc, còn mã ghi tệp WebP được gọi là trình ghi.
- uint16
- Số nguyên 16 bit, little-endian, chưa ký.
- uint24
- Một số nguyên 24 bit, little-endian, chưa ký.
- uint32
- Số nguyên 32 bit, little-endian, chưa ký.
- FourCC
- Mã gồm 4 ký tự (FourCC) là một uint32 được tạo bằng cách nối 4 ký tự ASCII theo thứ tự little-endian. Điều này có nghĩa là "aaaa" (0x61616161) và "AAAA" (0x41414141) được coi là các FourCCs khác nhau.
- Dựa trên 1
- Một trường số nguyên không dấu lưu trữ các giá trị được bù bằng
-1
, ví dụ: trường như vậy sẽ lưu trữ giá trị 25 dưới dạng 24. - ChunkHeader('ABCD')
- Dùng để mô tả tiêu đề FourCC và Chunk size của từng phân đoạn, trong đó "ABCD" là FourCC cho phân đoạn. Kích thước của phần tử này là 8 byte.
Định dạng tệp RIFF
Định dạng tệp WebP dựa trên định dạng tài liệu RIFF (Định dạng tệp trao đổi tài nguyên).
Phần tử cơ bản của tệp RIFF là một đoạn. Cấu trúc này bao gồm:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk FourCC |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Chunk Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Chunk Payload :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Chunk FourCC: 32 bit
- Mã ASCII gồm 4 ký tự dùng để nhận dạng đoạn.
- Kích thước đoạn: 32 bit (uint32)
- Kích thước của phân đoạn tính bằng byte, không bao gồm trường này, giá trị nhận dạng phân đoạn hoặc khoảng đệm.
- Trọng tải phân đoạn: Kích thước phân đoạn byte
- Tải trọng dữ liệu. Nếu Chunk size là số lẻ, một byte khoảng đệm đơn – mà PHẢI
là
0
để tuân thủ RIFF – sẽ được thêm vào.
Lưu ý: RIFF có quy ước là các FourCC của đoạn toàn chữ hoa là các đoạn tiêu chuẩn áp dụng cho mọi định dạng tệp RIFF, trong khi các FourCC dành riêng cho một định dạng tệp đều là chữ thường. WebP không tuân theo quy ước này.
Tiêu đề tệp WebP
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'R' | 'I' | 'F' | 'F' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| File Size |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| 'W' | 'E' | 'B' | 'P' |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- "RIFF": 32 bit
- Các ký tự ASCII "R", "I", "F", "F".
- Kích thước tệp: 32 bit (uint32)
- Kích thước của tệp tính bằng byte, bắt đầu từ độ dời 8. Giá trị tối đa của trường này là 2^32 trừ 10 byte, do đó kích thước của toàn bộ tệp tối đa là 4 GiB trừ 2 byte.
- "WEBP": 32 bit
- Các ký tự ASCII "W", "E", "B", "P".
Tệp WebP PHẢI bắt đầu bằng tiêu đề RIFF có FourCC "WEBP". Kích thước tệp trong tiêu đề là tổng kích thước của các đoạn theo sau cộng với 4
byte cho FourCC "WEBP". Tệp KHÔNG ĐƯỢC chứa bất kỳ dữ liệu nào sau dữ liệu do Kích thước tệp chỉ định. Trình đọc CÓ THỂ phân tích cú pháp các tệp như vậy, bỏ qua dữ liệu theo sau. Vì kích thước của bất kỳ đoạn nào đều bằng nhau, nên kích thước do tiêu đề RIFF đưa ra cũng bằng nhau. Nội dung của từng phần được mô tả trong các phần sau.
Định dạng tệp đơn giản (Mất dữ liệu)
BẠN NÊN sử dụng bố cục này nếu hình ảnh yêu cầu mã hoá mất dữ liệu và không yêu cầu tính năng trong suốt hoặc các tính năng nâng cao khác do định dạng mở rộng cung cấp. Các tệp có bố cục này có kích thước nhỏ hơn và được phần mềm cũ hỗ trợ.
Định dạng tệp WebP đơn giản (mất dữ liệu):
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| WebP file header (12 bytes) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: 'VP8 ' Chunk :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Mảnh "VP8":
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8 ') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: VP8 data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Dữ liệu VP8: Kích thước đoạn (byte)
- Dữ liệu luồng bit VP8.
Lưu ý rằng ký tự thứ tư trong 'VP8' FourCC là không gian ASCII (0x20).
Thông số kỹ thuật về định dạng luồng bit VP8 được mô tả trong Hướng dẫn giải mã và định dạng dữ liệu VP8. Xin lưu ý rằng tiêu đề khung VP8 chứa chiều rộng và chiều cao khung VP8. Đó được giả định là chiều rộng và chiều cao của canvas.
Thông số kỹ thuật VP8 mô tả cách giải mã hình ảnh thành định dạng Y'CbCr. Để chuyển đổi thành RGB, bạn nên sử dụng Suggested BT.601 (Đề xuất BT.601). Các ứng dụng CÓ THỂ sử dụng một phương thức chuyển đổi khác, nhưng kết quả trực quan có thể khác nhau giữa các bộ giải mã.
Định dạng tệp đơn giản (Không suy hao)
Lưu ý: Các đầu đọc cũ có thể không hỗ trợ các tệp sử dụng định dạng không suy hao.
BẠN NÊN sử dụng bố cục này nếu hình ảnh yêu cầu mã hoá không suy hao (có kênh độ trong suốt không bắt buộc) và không yêu cầu các tính năng nâng cao do định dạng mở rộng cung cấp.
Định dạng tệp WebP (không mất dữ liệu) đơn giản:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| WebP file header (12 bytes) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: 'VP8L' Chunk :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Phân đoạn "VP8L":
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8L') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: VP8L data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Dữ liệu VP8L: Kích thước đoạn (byte)
- Dữ liệu luồng bit VP8L.
Bạn có thể xem thông số kỹ thuật hiện tại của luồng bit VP8L tại Định dạng luồng bit không mất dữ liệu WebP. Xin lưu ý rằng tiêu đề VP8L chứa chiều rộng và chiều cao của hình ảnh là VP8L. Đó được giả định là chiều rộng và chiều cao của canvas.
Định dạng tệp mở rộng
Lưu ý: Các trình đọc cũ có thể không hỗ trợ các tệp sử dụng định dạng mở rộng.
Tệp định dạng mở rộng bao gồm:
Phân đoạn "VP8X" có thông tin về các tính năng được sử dụng trong tệp.
Một Mảnh "ICCP" không bắt buộc có hồ sơ màu.
Một Mảnh "ANIM" không bắt buộc có dữ liệu điều khiển ảnh động.
Dữ liệu hình ảnh.
Đoạn "EXIF" không bắt buộc có siêu dữ liệu Exif.
Phân đoạn "XMP" tuỳ chọn với siêu dữ liệu XMP.
Danh sách các đoạn không xác định (không bắt buộc).
Đối với ảnh tĩnh, dữ liệu hình ảnh chỉ có một khung duy nhất, cấu thành từ:
Phân đoạn phụ alpha không bắt buộc.
Đối với hình ảnh động, dữ liệu hình ảnh bao gồm nhiều khung hình. Bạn có thể xem thêm thông tin chi tiết về khung hình trong phần Ảnh động.
Tất cả các đoạn cần thiết để tái tạo và chỉnh màu, tức là "VP8X", "ICCP", "ANIM", "ANMF", "ALPH", "VP8" và "VP8L", PHẢI xuất hiện theo thứ tự mô tả trước đó. Trình đọc NÊN không thành công khi các đoạn cần thiết để tái tạo và chỉnh màu bị lộn thứ tự.
Siêu dữ liệu và phân đoạn không xác định CÓ THỂ xuất hiện không đúng thứ tự.
Lý do: Các đoạn cần thiết để tái tạo phải xuất hiện trước tiên trong tệp để cho phép trình đọc bắt đầu giải mã hình ảnh trước khi nhận được tất cả dữ liệu. Ứng dụng có thể hưởng lợi từ việc thay đổi thứ tự siêu dữ liệu và các đoạn tuỳ chỉnh cho phù hợp với quá trình triển khai.
Tiêu đề tệp WebP mở rộng:
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| |
| WebP file header (12 bytes) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('VP8X') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv|I|L|E|X|A|R| Reserved |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Canvas Width Minus One | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... Canvas Height Minus One |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Dành riêng (Rsv): 2 bit
- PHẢI là
0
. Trình đọc PHẢI bỏ qua trường này. - Cấu hình ICC (I): 1 bit
- Đặt nếu tệp chứa một Mảnh "ICCP".
- Alpha (L): 1 bit
- Đặt nếu bất kỳ khung hình nào của hình ảnh chứa thông tin về độ trong suốt ("alpha").
- Siêu dữ liệu Exif (E): 1 bit
- Đặt nếu tệp chứa siêu dữ liệu Exif.
- Siêu dữ liệu XMP (X): 1 bit
- Đặt nếu tệp chứa siêu dữ liệu XMP.
- Ảnh động (A): 1 bit
- Đặt nếu đây là ảnh động. Bạn nên dùng dữ liệu trong các đoạn "ANIM" và "ANMF" để kiểm soát ảnh động.
- Dành riêng (R): 1 bit
- PHẢI là
0
. Trình đọc PHẢI bỏ qua trường này. - Dành riêng: 24 bit
- PHẢI là
0
. Trình đọc PHẢI bỏ qua trường này. - Canvas Width Minus One (Chiều rộng canvas trừ đi 1): 24 bit Chiều rộng
- dựa trên 1 của canvas tính bằng pixel.
Chiều rộng thực tế của canvas là
1 + Canvas Width Minus One
. - Canvas Height Minus One (Chiều cao canvas trừ đi 1): 24 bit Chiều cao
- dựa trên 1 của canvas tính bằng pixel.
Chiều cao thực tế của canvas là
1 + Canvas Height Minus One
.
Hệ số của Chiều rộng canvas và Chiều cao canvas PHẢI là tối đa 2^32 - 1
.
Các thông số kỹ thuật trong tương lai có thể thêm các trường khác. BẠN PHẢI bỏ qua các trường không xác định.
Hoạt ảnh
Ảnh động được các đoạn "ANIM" và "ANMF" kiểm soát.
Mảnh "ANIM":
Đối với hình ảnh động, đoạn này chứa các thông số chung của ảnh động.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ANIM') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Background Color |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Loop Count |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Màu nền: 32 bit (uint32)
- Màu nền mặc định của canvas theo thứ tự byte [Blue, Green, Red, Alpha]. Màu này CÓ THỂ dùng để lấp đầy không gian không sử dụng trên canvas xung quanh khung hình, cũng như các pixel trong suốt của khung hình đầu tiên.
Màu nền cũng được dùng khi phương thức Xử lý là
1
.
Lưu ý:
Màu nền CÓ THỂ chứa giá trị alpha không mờ, ngay cả khi bạn không đặt cờ Alpha trong Mảnh "VP8X".
Ứng dụng trình xem PHẢI coi giá trị màu nền là gợi ý và không bắt buộc phải sử dụng giá trị này.
Canvas được xoá ở đầu mỗi vòng lặp. Bạn CÓ THỂ sử dụng màu nền để đạt được điều này.
- Số vòng lặp: 16 bit (uint16)
- Số lần lặp lại ảnh động. Nếu giá trị là
0
, thì giá trị này có nghĩa là vô hạn.
Phân đoạn này PHẢI xuất hiện nếu cờ Animation (Ảnh động) trong Phân đoạn "VP8X" được đặt. Nếu bạn không đặt cờ Animation (Ảnh động) và có khối này, thì bạn PHẢI bỏ qua khối này.
Mảnh 'ANMF':
Đối với hình ảnh động, đoạn này chứa thông tin về một khung hình. Nếu bạn không đặt Cờ ảnh động, thì phần này KHÔNG NÊN xuất hiện.
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ANMF') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Frame X | ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... Frame Y | Frame Width Minus One ...
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
... | Frame Height Minus One |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| Frame Duration | Reserved |B|D|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Frame Data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Khung X: 24 bit (uint24)
- Tọa độ X của góc trên bên trái khung hình là
Frame X * 2
. - Khung Y: 24 bit (uint24)
- Tọa độ Y của góc trên bên trái của khung là
Frame Y * 2
. - Chiều rộng khung trừ đi 1: 24 bit (uint24)
- Chiều rộng dựa trên 1 của khung.
Chiều rộng khung hình là
1 + Frame Width Minus One
. - Chiều cao khung hình trừ đi 1: 24 bit (uint24)
- Chiều cao dựa trên 1 của khung.
Chiều cao khung là
1 + Frame Height Minus One
. - Thời lượng khung hình: 24 bit (uint24)
- Thời gian chờ trước khi hiển thị khung tiếp theo, tính bằng đơn vị 1 mili giây. Lưu ý rằng việc diễn giải Thời lượng khung hình là 0 (và thường <= 10) được xác định bằng cách triển khai. Nhiều công cụ và trình duyệt chỉ định thời lượng tối thiểu tương tự như GIF.
- Dành riêng: 6 bit
- PHẢI
0
. Trình đọc PHẢI bỏ qua trường này. - Phương pháp trộn (B): 1 bit
Cho biết cách các pixel trong suốt của khung hình hiện tại được kết hợp với các pixel tương ứng của canvas trước đó:
0
: Sử dụng tính năng kết hợp alpha. Sau khi loại bỏ khung trước, hãy kết xuất khung hiện tại trên canvas bằng cách sử dụng tính năng kết hợp alpha (xem bên dưới). Nếu khung hình hiện tại không có kênh alpha, hãy giả định giá trị alpha là 255, thay thế hình chữ nhật một cách hiệu quả.1
: Không kết hợp. Sau khi loại bỏ khung trước, hãy kết xuất khung hiện tại trên canvas bằng cách ghi đè hình chữ nhật nằm trong khung hiện tại.
- Phương thức loại bỏ (D): 1 bit
Cho biết cách xử lý khung hình hiện tại sau khi hiển thị (trước khi hiển thị khung tiếp theo) trên canvas:
0
: Không huỷ bỏ. Giữ nguyên canvas.1
: Xử lý màu nền. Tô hình chữ nhật trên canvas được khung hiện tại bao phủ bằng màu nền được chỉ định trong Mảnh "ANIM".
Lưu ý:
Thao tác loại bỏ khung chỉ áp dụng cho hình chữ nhật của khung, tức là hình chữ nhật được xác định theo Khung X, Khung Y, chiều rộng khung và chiều cao khung. Ảnh này có thể che phủ toàn bộ ảnh in trên vải canvas hoặc không.
Kết hợp alpha:
Do mỗi kênh R, G, B và A có 8 bit và các kênh RGB không được nhân trước theo alpha, nên công thức để kết hợp 'dst' vào 'src' là:
blend.A = src.A + dst.A * (1 - src.A / 255) if blend.A = 0 then blend.RGB = 0 else blend.RGB = (src.RGB * src.A + dst.RGB * dst.A * (1 - src.A / 255)) / blend.A
Alpha-blging NÊN được thực hiện trong không gian màu tuyến tính, bằng cách xem xét hồ sơ màu của hình ảnh. Nếu không có cấu hình màu, thì giá trị RGB tiêu chuẩn (sRGB) sẽ được giả định. (Lưu ý rằng sRGB cũng cần được tuyến tính hoá do gamma khoảng 2,2.)
- Dữ liệu khung: Kích thước phân đoạn byte -
16
Bao gồm:
Phân đoạn alpha phụ không bắt buộc cho khung.
Một phân đoạn dòng bit cho khung.
Danh sách các đoạn không xác định (không bắt buộc).
Lưu ý: Trọng tải "ANMF", Dữ liệu khung, bao gồm các đoạn đã thêm khoảng đệm riêng lẻ, như mô tả trong định dạng tệp RIFF.
Alpha
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ALPH') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Rsv| P | F | C | Alpha Bitstream... |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Dành riêng (Rsv): 2 bit
- PHẢI là
0
. Trình đọc PHẢI bỏ qua trường này. - Xử lý trước (P): 2 bit
Các bit thông tin này được dùng để báo hiệu quá trình xử lý trước đã được thực hiện trong quá trình nén. Bộ giải mã có thể sử dụng thông tin này để làm nhiễu các giá trị hoặc làm mượt các độ dốc trước khi hiển thị.
0
: Không xử lý trước.1
: Giảm cấp.
Bộ giải mã không bắt buộc phải sử dụng thông tin này theo bất kỳ cách nào được chỉ định.
- Phương thức lọc (F): 2 bit
Các phương thức lọc được sử dụng được mô tả như sau:
0
: Không có.1
: Bộ lọc ngang.2
: Bộ lọc dọc.3
: Bộ lọc độ dốc.
Đối với mỗi điểm ảnh, việc lọc được thực hiện bằng cách sử dụng các phép tính sau.
Giả sử các giá trị alpha xung quanh vị trí X
hiện tại được gắn nhãn là:
C | B |
---+---+
A | X |
Chúng ta tìm cách tính toán giá trị alpha ở vị trí X
. Trước tiên, hệ thống sẽ đưa ra một dự đoán tuỳ thuộc vào phương thức lọc:
- Phương thức
0
: công cụ dự đoán = 0 - Phương thức
1
: predictor = A - Phương thức
2
: predictor = B - Phương thức
3
: predictor = clip(A + B - C)
trong đó clip(v)
bằng:
- 0 nếu v < 0,
- 255 nếu v > 255 hoặc
- v nếu không
Giá trị cuối cùng được lấy bằng cách thêm giá trị đã giải nén X
vào trình dự đoán và sử dụng phép tính modulo-256 để gói dải [256..511] vào dải [0..255]:
alpha = (predictor + X) % 256
Có một số trường hợp đặc biệt đối với các vị trí pixel ở ngoài cùng bên trái và trên cùng. Ví dụ: giá trị trên cùng bên trái tại vị trí (0, 0) sử dụng 0 làm giá trị dự đoán. Nếu không thì:
- Đối với các phương thức lọc theo chiều ngang hoặc độ dốc, các pixel ngoài cùng bên trái tại vị trí (0, y) được dự đoán bằng cách sử dụng vị trí (0, y-1) ngay ở trên.
- Đối với các phương thức lọc theo chiều dọc hoặc độ dốc, các pixel trên cùng tại vị trí (x, 0) được dự đoán bằng cách sử dụng vị trí (x-1, 0) ở bên trái.
- Phương pháp nén (C): 2 bit
Phương thức nén được sử dụng:
0
: Không nén.1
: Được nén bằng định dạng WebP không suy hao.
- Luồng bit alpha: Kích thước đoạn byte –
1
Luồng bit alpha đã mã hoá.
Phần không bắt buộc này chứa dữ liệu alpha đã mã hoá cho khung này. Khung chứa một Mảnh "VP8L" KHÔNG ĐƯỢC chứa mảnh này.
Lý do: Thông tin minh bạch đã có trong Phân đoạn "VP8L".
Dữ liệu kênh alpha được lưu trữ dưới dạng dữ liệu thô không nén (khi phương thức nén là "0") hoặc được nén bằng định dạng không mất dữ liệu (khi phương thức nén là "1").
Dữ liệu thô: Dữ liệu này bao gồm một chuỗi byte có độ dài = chiều rộng * chiều cao, chứa tất cả các giá trị độ trong suốt 8 bit theo thứ tự quét.
Nén định dạng không tổn hao: Trình tự byte là luồng hình ảnh nén (như mô tả trong "Định dạng luồng bit không tổn hao WebP") có kích thước ngầm ẩn chiều rộng x chiều cao. Tức là luồng hình ảnh này KHÔNG chứa bất kỳ tiêu đề nào mô tả kích thước hình ảnh.
Lý do: Các phương diện đã được biết từ các nguồn khác, vì vậy, việc lưu trữ lại các phương diện này sẽ là thừa và dễ xảy ra lỗi.
Sau khi luồng hình ảnh được giải mã thành các giá trị màu Alpha, Đỏ, Xanh lục, Xanh lam (ARGB), theo quy trình được mô tả trong quy cách định dạng không suy hao, thông tin về độ trong suốt phải được trích xuất từ kênh xanh lục của bộ tứ ARGB.
Lý do: Kênh màu xanh lục được phép thực hiện thêm các bước chuyển đổi trong quy cách – không giống như các kênh khác – có thể cải thiện khả năng nén.
Luồng Bit (VP8/VP8L)
Phân đoạn này chứa dữ liệu luồng bit được nén cho một khung.
Một đoạn luồng bit có thể là (i) Đoạn "VP8", sử dụng "VP8" (lưu ý khoảng trắng ký tự thứ tư quan trọng) làm FourCC, hoặc (ii) Đoạn "VP8L", sử dụng "VP8L" làm FourCC.
Định dạng của Phân đoạn "VP8" và "VP8L" như mô tả trong phần Định dạng tệp đơn giản (Mất) và Định dạng tệp đơn giản (Không tổn hao).
Hồ sơ màu
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('ICCP') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Color Profile :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Cấu hình màu: Kích thước phân đoạn byte
- Hồ sơ ICC.
Phần này PHẢI xuất hiện trước dữ liệu hình ảnh.
Chỉ được có nhiều nhất một đoạn như vậy. Nếu có nhiều đoạn như vậy, trình đọc CÓ THỂ bỏ qua tất cả trừ đoạn đầu tiên. Hãy xem Quy cách ICC để biết thông tin chi tiết.
Nếu không có đoạn này, bạn PHẢI giả định là sRGB.
Metadata
Siêu dữ liệu có thể được lưu trữ trong các Mảnh "EXIF" hoặc "XMP".
TỐI ĐA mỗi loại ('EXIF' và 'XMP ') chỉ nên có một đoạn. Nếu có nhiều đoạn như vậy, thì trình đọc CÓ THỂ bỏ qua tất cả trừ đoạn đầu tiên.
Các đoạn được xác định như sau:
Mảnh "EXIF":
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('EXIF') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Exif Metadata :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Siêu dữ liệu Exif: Kích thước khối tính bằng byte
- Siêu dữ liệu hình ảnh ở định dạng Exif.
Mảnh "XMP":
0 1 2 3
0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
| ChunkHeader('XMP ') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: XMP Metadata :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Siêu dữ liệu XMP: Kích thước đoạn (byte)
- Siêu dữ liệu hình ảnh ở định dạng XMP.
Lưu ý rằng ký tự thứ tư trong "XMP" FourCC là không gian ASCII (0x20).
Bạn có thể xem thêm hướng dẫn về cách xử lý siêu dữ liệu trong "Hướng dẫn xử lý siêu dữ liệu" của Nhóm làm việc về siêu dữ liệu.
Mảnh không xác định
Một đoạn RIFF (mô tả trong phần Định dạng tệp RIFF) có FourCC khác với bất kỳ đoạn nào được mô tả trong tài liệu này được coi là đoạn không xác định.
Lý do: Việc cho phép các đoạn không xác định sẽ cung cấp một điều khoản để mở rộng định dạng trong tương lai và cũng cho phép lưu trữ mọi dữ liệu dành riêng cho ứng dụng.
Tệp CÓ THỂ chứa các đoạn không xác định:
- ở cuối tệp, như mô tả trong phần Tiêu đề tệp WebP mở rộng hoặc
- ở cuối các Mảnh "ANMF", như mô tả trong phần Ảnh động.
Người đọc NÊN bỏ qua các phần này. Nhà văn NÊN giữ nguyên các phần này theo thứ tự ban đầu (trừ phi họ có ý định sửa đổi các phần này).
Tập hợp Canvas từ Khung
Ở đây, chúng tôi cung cấp thông tin tổng quan về cách người đọc PHẢI tập hợp một canvas trong trường hợp hình ảnh động.
Quá trình này bắt đầu bằng việc tạo một canvas bằng các kích thước được cung cấp trong khối "VP8X", rộng Canvas Width Minus One + 1
pixel và cao Canvas Height Minus
One + 1
pixel. Trường Loop Count
trong Phân đoạn "ANIM" kiểm soát số lần lặp lại quá trình tạo ảnh động. Đây là Loop Count - 1
đối với các giá trị Loop Count
khác 0 hoặc vô hạn nếu Loop Count
bằng 0.
Ở đầu mỗi vòng lặp, canvas được lấp đầy bằng màu nền từ Chunk "ANIM" hoặc màu do ứng dụng xác định.
Các đoạn "ANMF" chứa các khung hình riêng lẻ theo thứ tự hiển thị. Trước khi kết xuất từng khung hình, Disposal method
của khung hình trước đó sẽ được áp dụng.
Quá trình kết xuất khung hình đã giải mã bắt đầu tại toạ độ Descartes (2 *
Frame X
, 2 * Frame Y
), sử dụng góc trên cùng bên trái của canvas làm gốc.
Frame Width Minus One + 1
pixel rộng và Frame Height Minus One + 1
pixel
cao được kết xuất lên canvas bằng Blending method
.
Canvas hiển thị trong Frame Duration
mili giây. Quá trình này tiếp tục cho đến khi tất cả các khung hình do các Mảnh "ANMF" cung cấp đã hiển thị. Sau đó, một vòng lặp mới sẽ bắt đầu hoặc canvas sẽ được giữ nguyên ở trạng thái cuối cùng nếu tất cả các vòng lặp đã hoàn tất.
Mã giả sau minh hoạ quá trình kết xuất. Ký hiệu VP8X.field có nghĩa là trường trong Phân đoạn "VP8X" có cùng nội dung mô tả.
VP8X.flags.hasAnimation MUST be TRUE
canvas ← new image of size VP8X.canvasWidth x VP8X.canvasHeight with
background color ANIM.background_color or
application-defined color.
loop_count ← ANIM.loopCount
dispose_method ← Dispose to background color
if loop_count == 0:
loop_count = ∞
frame_params ← nil
next chunk in image_data is ANMF MUST be TRUE
for loop = 0..loop_count - 1
clear canvas to ANIM.background_color or application-defined color
until eof or non-ANMF chunk
frame_params.frameX = Frame X
frame_params.frameY = Frame Y
frame_params.frameWidth = Frame Width Minus One + 1
frame_params.frameHeight = Frame Height Minus One + 1
frame_params.frameDuration = Frame Duration
frame_right = frame_params.frameX + frame_params.frameWidth
frame_bottom = frame_params.frameY + frame_params.frameHeight
VP8X.canvasWidth >= frame_right MUST be TRUE
VP8X.canvasHeight >= frame_bottom MUST be TRUE
for subchunk in 'Frame Data':
if subchunk.tag == "ALPH":
alpha subchunks not found in 'Frame Data' earlier MUST be
TRUE
frame_params.alpha = alpha_data
else if subchunk.tag == "VP8 " OR subchunk.tag == "VP8L":
bitstream subchunks not found in 'Frame Data' earlier MUST
be TRUE
frame_params.bitstream = bitstream_data
apply dispose_method.
render frame with frame_params.alpha and frame_params.bitstream
on canvas with top-left corner at (frame_params.frameX,
frame_params.frameY), using Blending method
frame_params.blendingMethod.
canvas contains the decoded image.
Show the contents of the canvas for
frame_params.frameDuration * 1 ms.
dispose_method = frame_params.disposeMethod
Bố cục tệp mẫu
Hình ảnh được mã hoá có tổn hao với alpha có thể có dạng như sau:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- ALPH (alpha bitstream)
+- VP8 (bitstream)
Hình ảnh được mã hoá không suy hao có thể có dạng như sau:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- VP8L (lossless bitstream)
+- XYZW (unknown chunk)
Hình ảnh không tổn hao có cấu hình ICC và siêu dữ liệu XMP có thể có dạng như sau:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- ICCP (color profile)
+- VP8L (lossless bitstream)
+- XMP (metadata)
Hình ảnh động có siêu dữ liệu Exif có thể có dạng như sau:
RIFF/WEBP
+- VP8X (descriptions of features used)
+- ANIM (global animation parameters)
+- ANMF (frame1 parameters + data)
+- ANMF (frame2 parameters + data)
+- ANMF (frame3 parameters + data)
+- ANMF (frame4 parameters + data)
+- EXIF (metadata)