Giới thiệu
WebP là định dạng hình ảnh sử dụng (i) phương thức mã hoá khung khoá 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 giao thức mã hoá này sẽ mang lại hiệu quả cao hơn so với các định dạng cũ, chẳng hạn như JPEG, GIF và PNG. API này được tối ưu hoá để chuyển hình ảnh nhanh qua mạng (ví dụ: cho trang web). Định dạng WebP có tính năng tương đương (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 trên và trên trường hợp sử dụng cơ bản của WebP (tức là một tệp chứa một hình ảnh duy nhất được mã hoá dưới dạng khung khoá VP8). Vùng chứa WebP hỗ trợ thêm cho các mục sau:
Nén không tổn hao: Hình ảnh có thể được nén không tổn hao bằng Định dạng không tổn hao ở định dạng WebP.
Siêu dữ liệu: Một hình ảnh có thể lưu trữ siêu dữ liệu ở định dạng Tệp hình ảnh trao đổi (Exif) hoặc Nền tảng siêu dữ liệu mở rộng (XMP).
Độ trong suốt: Một hình ảnh có thể có độ trong suốt, tức là kênh alpha.
Hồ sơ màu: Một hình ảnh có thể có hồ sơ ICC được nhúng theo mô tả của International Color Consortium.
Ảnh động: Một hình ảnh có thể có nhiều khung hình với các điểm 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 | hình ảnh/webp |
Số nhận dạng loại thống nhất | org.webmproject.webp |
Thuật ngữ và khái niệm cơ bản
Các từ khoá "PHẢI", "KHÔNG ĐƯỢC", "BẮT BUỘC", "SÓNG", "KHÔNG NÊN", "NÊN", "KHÔNG NÊN", "ĐƯỢC ĐỀ XUẤT", "KHÔNG NÊN", "CÓ THỂ" và "KHÔNG BẮT BUỘC" trong tài liệu này được hiểu như mô tả trong BCP 14 RFC 2119 RFC 8174 khi và chỉ khi nào chúng xuất hiện bằng mọi chữ viết hoa như trình bày ở đây.
Tệp WebP chứa hình ảnh tĩnh (tức là một ma trận pixel được mã hoá) hoặc ảnh động. (Không bắt buộc) Tệp này cũng có thể chứa thông tin về độ trong suốt, cấu hình 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ơ đồ phân đoạn bắt đầu từ 0
đối với bit quan trọng 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 xuyên suốt tài liệu này:
- Người đọc/Người viết
- Mã đọc tệp WebP được gọi là trình đọc, còn mã viết các tệp này thì được gọi là trình ghi.
- uint16
- Một số nguyên 16 bit, có phân cuối nhỏ, không dấu.
- uint24
- Một số nguyên 24 bit, có phân cuối nhỏ, không dấu.
- uint32
- Một số nguyên 32 bit, nhỏ, không dấu.
- 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ự cuối nhỏ. Đ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 chưa ký lưu trữ giá trị bù trừ bằng
-1
, chẳng hạn như 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 (Kích thước phân đoạn) 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. Chương trình 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ự được dùng để nhận dạng phân đoạn.
- Kích thước phân đ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.
- Tải trọng phân đoạn: Kích thước phân đoạn byte
- Tải trọng dữ liệu. Nếu Chunk Size (Kích thước đoạn) là số lẻ, thì 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 là các đoạn FourCC viết hoa toàn bộ là các phân đoạn tiêu chuẩn áp dụng cho mọi định dạng tệp RIFF, trong khi 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ừ độ lệch 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ó chữ "WEBP" của FourCC. Kích thước tệp trong tiêu đề là tổng kích thước của các phân đoạn theo sau cộng thêm 4
byte của FourCC "WEBP". Tệp KHÔNG ĐƯỢC chứa bất kỳ dữ liệu nào sau dữ liệu được chỉ định bởi Kích thước tệp. 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 mọi phân đoạn đều là đồng đều, nên kích thước mà tiêu đề RIFF cung cấp 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 tích)
Bố cục này NÊN được sử dụng nếu hình ảnh yêu cầu mã hóa lossy và không yêu cầu độ trong suốt hoặc các tính năng nâng cao khác được cung cấp bởi định dạng mở rộng. Tệp có bố cục này nhỏ hơn và được phần mềm cũ hỗ trợ.
Định dạng tệp WebP (bóng) đơ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 :
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
Phân đoạn "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 phân đoạn byte
- Dữ liệu luồng bit VP8.
Lưu ý rằng ký tự thứ tư trong "VP8" FourCC là một 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 của khung VP8. Giá trị này giả định là chiều rộng và chiều cao của canvas.
Thông số kỹ thuật của VP8 mô tả cách giải mã hình ảnh sang định dạng Y'CbCr. Để chuyển đổi sang RGB, Recommendation BT.601 nên be used. 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 tổn hao)
Lưu ý: Những độc giả lớn tuổi có thể không hỗ trợ tệp sử dụng định dạng không tổn hao.
Bố cục này NÊN được sử dụng nếu hình ảnh yêu cầu lossless mã hoá (với một kênh trong suốt tuỳ chọn) và không yêu cầu các tính năng nâng cao được cung cấp bởi định dạng mở rộng.
Đị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 phân đ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 tổn hao 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á trị này đượ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 giả lớn tuổi có thể không hỗ trợ 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 dùng trong tệp.
Phân đoạn "ICCP" không bắt buộc có cấu hình màu.
Một Phân đoạn "ANIM" không bắt buộc có dữ liệu điều khiển hiệu ứng chuyển động.
Dữ liệu hình ảnh.
Một phân đ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 không bắt buộc gồm các phân đoạn không xác định.
Đối với hình ảnh tĩnh, dữ liệu hình ảnh bao gồm một khung duy nhất, bao gồm:
Một phân đoạn alpha không bắt buộc.
Đối với ả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 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ự như mô tả trước đó. Độc giả 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 không theo thứ tự.
Các phần Siêu dữ liệu và không xác định có thể xuất hiện không đúng thứ tự.
Rationale: Các đoạn cần thiết để tạo lại 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ự siêu dữ liệu và các phân đoạn tuỳ chỉnh cho phù hợp với cách 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 Phân đoạn "ICCP".
- Alpha (L): 1 bit
- Đặt nếu bất kỳ khung 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
- Thiết lập xem tệp có chứa siêu dữ liệu Exif hay không.
- Siêu dữ liệu XMP (X): 1 bit
- Thiết lập 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 Chunk "ANIM" và "ANMF" để kiểm soát ảnh động.
- Đặt trước (R): 1 bit
- PHẢI
0
. Độc giả PHẢI bỏ qua trường này. - Đặt trước: 24 bit
- PHẢI
0
. Độc giả PHẢI bỏ qua trường này. - Chiều rộng canvas trừ một: 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
. - Chiều cao canvas trừ một: 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
.
Sản phẩm của Canvas Width (Chiều rộng canvas) và Canvas Height (Chiều cao canvas) PHẢI tối đa là 2^32 - 1
.
Quy cách trong tương lai có thể thêm nhiều trường hơn. PHẢI bỏ qua các trường không xác định.
Hoạt ảnh
Ảnh động do các Chunk "ANIM" và "ANMF" kiểm soát.
Phân đoạn "ANIM":
Đối với hình ảnh động, đoạn này chứa các tham 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 là [Xanh dương, Xanh lục, Đỏ, 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, cũng như các pixel trong suốt của khung đầu tiên.
Màu nền cũng được sử 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 cờ Alpha trong Phân đoạn "VP8X" không được đặt.
Các ứng dụng trình xem NÊN 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 sẽ bị xoá ở đầu mỗi vòng lặp. Màu nền CÓ THỂ được sử dụng để đạ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 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 trong Phân đoạn "VP8X" được đặt. Nếu cờ Animation không được đặt và đoạn này đã có, thì PHẢI bỏ qua.
Phân đoạn "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 ĐƯỢC 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 của 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 hình là
Frame Y * 2
. - Chiều rộng khung hình trừ một: 24 bit (uint24)
- Chiều rộng dựa trên 1 của khung hình.
Chiều rộng khung 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 hình.
Chiều cao khung hình 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 hình 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 theo 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ư ả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 kết hợp pixel trong suốt của khung hình hiện tại với các pixel tương ứng của canvas trước đó:
0
: Sử dụ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 trộn alpha (xem bên dưới). Nếu khung hiện tại không có kênh alpha, hãy giả định giá trị alpha là 255, thay thế hiệu quả hình chữ nhật.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ó trong khung hiện tại.
- Phương pháp loại bỏ (D): 1 bit
Cho biết cách xử lý khung hiện tại sau khi hiển thị (trước khi kết xuất khung tiếp theo) trên canvas:
0
: Không được vứt bỏ. Giữ nguyên canvas.1
: Loại bỏ màu nền. Điền vào hình chữ nhật trên canvas được bao phủ bởi khung hiện tại bằng màu nền được chỉ định trong 'ANIM' Chunk.
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 được xác định bởi Frame X, Frame Y, chiều rộng khung và chiều cao khung. Có thể phủ toàn bộ ảnh in trên vải canvas hoặc không.
Trộn alpha:
Giả sử mỗi kênh R, G, B và A đều là 8 bit và các kênh RGB không được nhân trước bằng 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
Bạn nên thực hiện việc trộn alpha trong hệ màu tuyến tính bằng cách tính đến cấu hình màu của hình ảnh. Nếu không có cấu hình màu, thì hệ thống sẽ giả định RGB tiêu chuẩn (sRGB). (Xin 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 –
16
byte Bao gồm:
Một phân đoạn alpha không bắt buộc cho khung.
Một phân đoạn con trong luồng bit cho khung.
Danh sách không bắt buộc gồm các phân đoạn không xác định.
Lưu ý: Tải trọng "ANMF", Dữ liệu khung, bao gồm các phần được đệm riêng lẻ, như được mô tả trong định dạng tệp RFF.
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 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 để chẳng hạn như phối màu các giá trị hoặc làm mịn chuyển màu trước khi hiển thị.
0
: Không xử lý trước.1
: Giảm cấp.
Không bắt buộc phải có bộ giải mã để sử dụng thông tin này theo bất kỳ cách nào được chỉ định.
- Phương pháp lọc (F): 2 bit
Các phương thức lọ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 chuyển màu.
Đối với mỗi pixel, quá trình lọc được thực hiện theo các phép tính sau đây.
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, thông tin dự đoán được đưa ra tuỳ thuộc vào phương thức lọc:
- Phương pháp
0
: công cụ dự đoán = 0 - Phương pháp
1
: công cụ dự đoán = A - Phương pháp
2
: công cụ dự đoán = B - Phương pháp
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
- so với
Giá trị cuối cùng được tính bằng cách thêm giá trị đã giải nén X
vào bộ dự đoán và sử dụng số học modulo-256 để gói dải ô [256..511] thành giá trị [0..255]:
alpha = (predictor + X) % 256
Có các trường hợp đặc biệt đối với các vị trí pixel ở ngoài cùng bên trái và ngoài cùng bên trái. 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ì hãy làm như sau:
- Đối với phương thức lọc theo chiều ngang hoặc kiểu chuyển màu, 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 phía trên.
- Đối với phương thức lọc dọc hoặc lọc chuyển màu, 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 đã 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 phân đoạn –
1
byte Luồng bit alpha đã mã hóa.
Phân đoạn không bắt buộc này chứa dữ liệu alpha được mã hoá cho khung này. Một khung chứa Phân đoạn "VP8L" KHÔNG ĐƯỢC chứa phân đoạn này.
Rationale: 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 theo chiều 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: Chuỗi byte là một luồng hình ảnh nén (như mô tả trong "Định dạng luồng dữ liệu không mất dữ liệu WebP") có kích thước ngầm định chiều rộng x chiều cao. Điều đó nghĩa 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.
Rationale: Các kích thước đã được xác định từ các nguồn khác, vì vậy, việc lưu trữ lại các kích thước đó sẽ dư 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 dương (ARGB), theo quy trình được mô tả trong thông số kỹ thuật về định dạng không tổn hao, thông tin về độ trong suốt phải được trích xuất từ kênh xanh lục của bộ bốn ARGB.
Rationale: Kênh màu xanh lục được phép thực hiện các bước biến đổi bổ sung trong thông số kỹ thuật (không giống như các kênh khác) có thể cải thiện độ nén.
Luồng bit (VP8/VP8L)
Đoạn này chứa dữ liệu luồng bit được nén cho một khung.
Đoạn luồng bit có thể là (i) Phân đoạn "VP8", sử dụng "VP8" (lưu ý không gian ký tự thứ tư quan trọng) như FourCC, hoặc (ii) Phân đoạn "VP8L", sử dụng "VP8L" làm FourCC.
Định dạng của khối "VP8" và "VP8L" lần lượt được mô tả trong các phần: Định dạng tệp đơn giản (Lossy) và Định dạng tệp đơn giản (không mất tích).
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.
Đoạn này PHẢI xuất hiện trước dữ liệu hình ảnh.
NÊN có tối đa một phân đoạn như vậy. Nếu có nhiều phân đoạn như vậy, độc giả CÓ THỂ bỏ qua tất cả, ngoại trừ phân đoạn đầu tiên. Xem Quy cách của ICC để biết chi tiết.
Nếu không có đoạn này, bạn NÊN giả định sRGB.
Metadata
Siêu dữ liệu có thể được lưu trữ trong các phân đoạn "EXIF" hoặc "XMP".
There Hệ thống sẽ có tối đa một đoạn của từng loại ('EXIF' và 'XMP '). Nếu có thêm các chunks khác, người đọc CÓ THỂ bỏ qua tất cả ngoại trừ bản dịch đầu tiên.
Các phần được xác định như sau:
Phân đoạn "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 phân đoạn byte
- Siêu dữ liệu hình ảnh ở định dạng Exif.
Phân đoạn "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à một dấu cách 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 hoạt động siêu dữ liệu.
Phân đoạn không xác định
Một phân đoạn RIFF (được mô tả trong phần Định dạng tệp RIFF) có FourCC khác với bất kỳ phân đoạn nào được mô tả trong tài liệu này sẽ được coi là một phân đoạn không xác định.
Rationale: Việc cho phép các phân đoạn không xác định sẽ cung cấp điều khoản cho việc 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 Phân đoạn "ANMF", như mô tả trong phần Ảnh động.
Độc giả NÊN bỏ qua các phân đoạn này. Người viết NÊN lưu giữ chúng theo thứ tự ban đầu (trừ khi họ có ý định cụ thể sửa đổi các đoạn này).
Lắp ráp canvas từ khung
Ở đây, chúng tôi cung cấp thông tin tổng quan về cách độc giả PHẢI lắp ráp một bức ảnh in trên vải canvas trong trường hợp là một hình ảnh động.
Quá trình này bắt đầu bằng việc tạo một canvas sử dụng kích thước được cung cấp trong Phân đoạn "VP8X", Canvas Width Minus One + 1
pixel rộng x Canvas Height Minus
One + 1
pixel. Trường Loop Count
trong Chunk "ANIM" kiểm soát số lần quá trình lặp lại ả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 lần lặp lại của vòng lặp, canvas sẽ được tô bằng màu nền từ Phân đoạn "ANIM" hoặc màu do ứng dụng xác định.
Các phân đoạn "ANMF" chứa các khung riêng lẻ được cung cấp theo thứ tự hiển thị. Trước khi kết xuất từng khung hình, Disposal method
của khung trước sẽ được áp dụng.
Quá trình kết xuất khung đã 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.
Frame Width Minus One + 1
pixel rộng x cao Frame Height Minus One + 1
pixel được kết xuất trên canvas bằng cách sử dụng Blending method
.
Canvas sẽ hiển thị trong Frame Duration
mili giây. Quá trình này sẽ tiếp tục cho đến khi tất cả khung do Chunk "ANMF" cung cấp được hiển thị. Sau đó, một vòng lặp mới sẽ được bắt đầu hoặc canvas sẽ ở trạng thái cuối cùng nếu tất cả các vòng lặp đều đã hoàn tất.
Mã giả sau đây 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
Ví dụ về bố cục tệp
Hình ảnh được mã hoá có tổn hao có 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 tổn 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)