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 nên hiệu quả hơn so với các định dạng cũ như JPEG, GIF và PNG. Giao diện này được tối ưu hoá để truyền hình ảnh nhanh qua mạng (cho ví dụ: đối với trang web). Định dạng WebP có tính năng tương đương (hồ sơ màu sắc, 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 dành cho WebP) cho phép hỗ trợ tính năng và cao hơn 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 được mã hoá dưới dạng khung chính VP8). Vùng chứa WebP cung cấp thêm hỗ trợ các tính năng sau:
Nén không tổn hao: Có thể nén hình ảnh không tổn hao bằng cách sử dụng Định dạng WebP không tổn hao.
Siêu dữ liệu: Một hình ảnh có thể đã lưu trữ siêu dữ liệu trong Tệp hình ảnh có thể trao đổi Định dạng (Exif) hoặc Nền tảng siêu dữ liệu có thể 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 (Hội đồng 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 khi tham chiếu đến WebP container:
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 |
Mã 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. Nếu muốn, tệp này cũng có thể chứa độ trong suốt , hồ sơ màu và siêu dữ liệu. Chúng tôi gọi ma trận pixel là canvas của hình ảnh.
Việc đánh số bit trong sơ đồ khối 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
- Một số nguyên 16 bit có đuôi nhỏ, chưa ký.
- uint24
- Một số nguyên 24 bit có đuôi nhỏ, 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 bốn ký tự ASCII theo thứ tự little-endian. Điều này có nghĩa là "aaaa" (0x61616161) và "AAAA" (0x41414141) được coi là 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ị bù trừ bằng
-1
, chẳng hạn như trường sẽ lưu trữ giá trị 25 thành 24. - ChunkHeader('ABCD')
- Dùng để mô tả tiêu đề FourCC và Chunk Size (Kích thước đoạn) của từng đoạn, trong đó "ABCD" là FourCC cho đ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 :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Phân đoạn 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, phân đoạn giá trị nhận dạng hoặc khoảng đệm.
- Trọng tải phân đoạn: Kích thước phân đoạn byte
- Gói dữ liệu. Nếu Phân đoạn Kích thước là số lẻ, một byte khoảng đệm duy nhất – PHẢI
là
0
để tuân thủ RIFF -- sẽ được thêm vào.
Lưu ý: RIFF có quy ước rằng FourCC được viết hoa toàn bộ là tiêu chuẩn phân đoạn áp dụng cho bất kỳ định dạng tệp RIFF nào, trong khi FourCC dành riêng cho một 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ị lớn nhất của trường này là 2^32 trừ đi 10 byte và do đó kích thước của toàn bộ tệp là ở mức tối đa 4 GiB trừ đi 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ó mã 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. Người đọc CÓ THỂ phân tích cú pháp các tệp này, bỏ qua phần đuôi tệp
. Vì kích thước của bất kỳ phần nào đều là số chẵn, nên kích thước do tiêu đề RIFF cung cấp cũng là số chẵn. 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)
Bố cục này NÊN được sử dụng 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 (bị mất) đơ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) |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: 'VP8 ' Chunk :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
"VP8" Phân đoạ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('VP8 ') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: VP8 data :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Dữ liệu VP8: Kích thước đoạn (byte)
- Dữ liệu luồng bit của VPN.
Xin lưu ý rằng ký tự thứ tư trong FourCC "VP8" là một khoảng trắng 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. Người nhận chuyển đổi thành RGB, thì bạn NÊN sử dụng Đề xuất BT.601. Ứ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 tổn 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 :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Mảnh "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 phân đoạn byte
- Dữ liệu luồng bit VP8L.
Bạn có thể tìm thấy 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 tổn hao trên WebP. Xin lưu ý rằng tiêu đề VP8L chứa chiều rộng và chiều cao của hình ảnh VP8L. Giả định là chiều rộng và chiều cao của canvas.
Định dạng tệp mở rộng
Lưu ý: Người đọc lớn tuổi 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:
Một Mảnh "VP8X" chứa thông tin về các tính năng được sử dụng trong tệp.
"ICCP" không bắt buộc Phân đoạn có cấu hình 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.
Giá trị "EXIF" không bắt buộc Phân đoạn bằng siêu dữ liệu Exif.
"XMP" tuỳ chọn Phân đoạn bằng siêu dữ liệu XMP.
Danh sách đ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ỉ bao gồm một khung duy nhất được tạo lên trong số:
Phân đoạn phụ alpha không bắt buộc.
Một phân đoạn dòng bit.
Đối với hình ảnh động, dữ liệu hình ảnh bao gồm nhiều khung. 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 cho việc tái cấu trúc và chỉnh màu, đó là "VP8X", "ICCP", "ANIM", "ANMF", "ALPH", "VP8" và "VP8L", PHẢI xuất hiện theo thứ tự được mô tả trước đó. Trình đọc PHẢI không thành công khi các đoạn cần thiết để tái tạo và chỉnh màu không đúng thứ tự.
Các đoạn Siêu dữ liệu và không xác định CÓ THỂ xuất hiện không theo thứ tự.
Rationale: Các đoạn cần thiết để tái tạo sẽ xuất hiện đầu tiên trong tệp để cho phép người đọc bắt đầu giải mã hình ảnh trước khi nhận được tất cả dữ liệu. Một ứng dụng có thể hưởng lợi từ việc thay đổi thứ tự của siêu dữ liệu và các đoạn tuỳ chỉnh để phù hợp với việc 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
0
. Độc giả PHẢI bỏ qua trường này. - Cấu hình ICC (I): 1 bit
- Đặt nếu tệp chứa "ICCP" Phân đoạn.
- 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. Dữ liệu trong "ANIM" và "ANMF" Đoạn nên là dùng để điều khiển ảnh động.
- Đã đặt trước (R): 1 bit
- PHẢI là
0
. Trình đọc PHẢI bỏ qua trường này. - Đã đặt trước: 24 bit
- PHẢI
0
. Trình đọc PHẢI bỏ qua trường này. - 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 do "ANIM" kiểm soát và "ANMF" Viên nhỏ.
Mảnh "ANIM":
Đối với hình ảnh động, đoạn này chứa các thông số toàn cục 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]. Bạn CÓ THỂ sử dụng màu này để lấp đầy không gian không sử dụng trên canvas xung quanh các khung, cũng như các pixel trong suốt của khung đầu tiên.
Màu nền cũng được dùng khi phương thức Loại bỏ là
1
.
Lưu ý:
Màu nền CÓ THỂ chứa giá trị alpha không mờ, ngay cả khi giá trị Cờ Alpha trong 'VP8X' Đã huỷ đặt phân đoạn.
Ứng dụng của trình xem PHẢI coi giá trị màu nền là gợi ý và thì bạn không bắt buộc phải sử dụng mã này.
Canvas được xoá ở đầu mỗi vòng lặp. Màu nền CÓ THỂ là dùng để đạt được mục tiê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
, điều 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 "VP8X" Đã đặt phân đoạn. 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.
"ANMF" Phân đoạn:
Đố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 hình X: 24 bit (uint24)
- Toạ độ X của góc trên bên trái của khung là
Frame X * 2
. - Khung hình 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ừ một: 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) là được xác định bởi quá trình 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.
- Đã đặt trước: 6 bit
- PHẢI
0
. Độc giả PHẢI bỏ qua trường này. - Phương pháp trộn (B): 1 bit
Cho biết cách pha trộn các pixel trong suốt của khung hình hiện tại bằng 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 được bao phủ bởi khung hiện tại.
- Phương thức xử lý (D): 1 bit
Cho biết cách xử lý khung hình hiện tại sau khi được hiển thị (trước khi hiển thị khung tiếp theo) trên canvas:
0
: Đừng vứt bỏ. Giữ nguyên ảnh in trên vải canvas.1
: Chuyển sang màu nền. Điền thông tin vào hình chữ nhật trên canvas được phủ bởi khung hiện tại bằng màu nền được chỉ định trong "ANIM" Phân đoạn.
Lưu ý:
Việc loại bỏ khung chỉ áp dụng cho hình chữ nhật khung, tức là hình chữ nhật do Khung X, Khung Y, chiều rộng khung và chiều cao khung xác định. Ả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:
Giả sử mỗi kênh R, G, B và A là 8 bit và RGB kênh không được nhân trước với alpha, 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
Phối hợp alpha PHẢI được thực hiện trong hệ màu tuyến tính, có tính đến hồ sơ màu của hình ảnh. Nếu không có hồ sơ màu, thì RGB chuẩn (sRGB) sẽ được giả định. (Xin lưu ý rằng sRGB cũng cần được tuyến tính hóa do gamma ~ 2.2.)
- Dữ liệu khung: Kích thước đ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 đã đệ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
0
. Độc giả 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 theo chiều ngang.2
: Bộ lọc dọc.3
: Bộ lọc độ dốc.
Đối với mỗi pixel, quá trình lọc được thực hiện bằ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 tại 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
: predictor = 0 - Phương thức
1
: công cụ dự đoán = A - Phương thức
2
: predictor = B - Phương thức
3
: công cụ dự đoán = 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 tính bằng cách thêm giá trị đã giải nén X
vào
dự đoán và sử dụng số học modulo-256 để gói phạm vi [256..511]
vào tệp [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 phương pháp lọc theo chiều ngang hoặc độ dố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 thức 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 tổn 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 có chứa "VP8L" Phân đoạn KHÔNG ĐƯỢC chứa phân đoạn này.
Lý do: Thông tin về tính 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 tổn hao (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à, image-stream KHÔNG chứa bất kỳ tiêu đề nào mô tả kích thước hình ảnh.
Rationale: Phương diện đã được xác định từ các nguồn khác, vì vậy, việc lưu trữ chúng lần nữa sẽ dư thừa và dễ bị 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 này chứa dữ liệu luồng bit nén cho một khung hình.
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.
Các định dạng của "VP8" và "VP8L" Các đoạn được mô tả trong các 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).
Cấu hình 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 đoạ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. Xem Thông số kỹ thuật ICC để biết 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 "EXIF" hoặc 'XMP' Viên nhỏ.
PHẢI có tối đa một phân đoạn thuộc mỗi loại ("EXIF" và "XMP"). Nếu có có nhiều phần như vậy hơn, nên người đọc CÓ THỂ bỏ qua tất cả ngoại trừ phần đầu tiên.
Các đoạn được xác định như sau:
"EXIF" Phân đoạ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('EXIF') |
| |
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
: Exif Metadata :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
- Siêu dữ liệu Exif: Kích thước khối (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 phân đ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 "Nguyên tắc xử lý siêu dữ liệu" của Nhóm làm việc về siêu dữ liệu.
Đoạn 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.
Rationale: Việc cho phép các đoạn không xác định sẽ cấp quyền mở rộng trong tương lai của định dạng đó đồng thời 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 'ANMF' Đoạn, như được mô tả trong Ảnh động.
Trình đọc NÊN bỏ qua các đoạn này. Người viết NÊN lưu giữ chúng trong đơn đặt hàng ban đầu (trừ phi họ có ý định cụ thể là sửa đổi những đoạ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
từ Mảnh "ANIM" kiểm soát số lần lặp lại quy trình ả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 cách sử dụng màu nền từ 'ANIM' Phân đoạn 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
mỗi khung hình, Disposal method
của khung trước đó sẽ được áp dụng.
Quá trình hiển thị khung được 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 điểm gốc.
rộng Frame Width Minus One + 1
pixel x Frame Height Minus One + 1
pixel
cao sẽ được hiển thị trên canvas bằng Blending method
.
Canvas sẽ 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 lặp lại 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 Đ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)
Một 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)