PNG là sự kết hợp của Bộ lọc + LZ77 + Huffman (sự kết hợp của LZ77 + Huffman được gọi là Deflate) theo thứ tự đó:
bước 1) nếu bộ lọc khác với Không có, giá trị của các pixel được thay thế bằng chênh lệch so với các pixel liền kề (để biết thêm chi tiết, hãy xem http://www.libpng.org/pub/png/book/ch CHƯƠNG09.html ) . Điều đó làm tăng khả năng nén hình ảnh với độ dốc (vì vậy ... 4 5 6 7 trở thành ... 1 1 1 1) và nó có thể giúp trong các khu vực có cùng màu (... 3 3 3 5 5 5 5 5 trở thành 0 0 0 2 0 0 0 0 0). Theo mặc định, các bộ lọc được bật trong hình ảnh 24 bit và bị vô hiệu hóa trong hình ảnh 8 bit với bảng màu.
bước 2) dữ liệu được nén bằng LZ77 thay thế các chuỗi byte lặp lại (khớp) bằng một tuple chứa khoảng cách đến khớp và độ dài của khớp.
bước 3) kết quả của bước 2 được mã hóa bằng mã Huffman thay thế các ký hiệu có độ dài cố định bằng mã có độ dài thay đổi, ký hiệu càng thường xuyên thì mã càng ngắn.
Có nhiều vấn đề:
Một thay đổi nhỏ ảnh hưởng đến một vài pixel sẽ dẫn đến thay đổi kết quả từ 3 bước nén png:
1) Giá trị được lọc của các pixel liền kề sẽ thay đổi (tùy thuộc vào bộ lọc được sử dụng). Điều đó sẽ khuếch đại tác động của những thay đổi nhỏ.
2) Thay đổi sẽ có nghĩa là phù hợp với khu vực đó sẽ khác nhau. Ví dụ: thay đổi 333333 thành 333533 vì một lần xuất hiện khác của 333333 sẽ không còn khớp nữa nên nó sẽ chọn một kết quả khác thành 333333 với một khoảng cách khác hoặc nó sẽ chọn cùng một trận đấu nhưng với độ dài ngắn hơn và sau đó là một trận đấu khác cho 3 byte cuối cùng. Tự nó sẽ thay đổi kết quả rất nhiều.
3) Vấn đề lớn nhất là ở bước 3. Mã huffman sử dụng số bit thay đổi, do đó, ngay cả một thay đổi nhỏ cũng sẽ dẫn đến việc mọi thứ tiếp theo không được căn chỉnh nữa. AFAIK Hầu hết các thuật toán nén không thể phát hiện các kết quả khớp không phải là byte do đó sẽ ngăn chặn (hoặc ít nhất là giảm rất nhiều) việc nén dữ liệu đã theo sau thay đổi trừ khi máy nén có thể phát hiện các kết quả khớp không được căn chỉnh byte.
Các vấn đề khác đã được trả lời bởi các trả lời khác:
4) Gzip sử dụng cùng một thuật toán Deflate với từ điển 32KB, vì vậy nếu các tệp png lớn hơn 32KB, các kết quả trùng khớp sẽ không được phát hiện ngay cả khi chúng giống hệt nhau. Bzip2 tốt hơn ở khía cạnh đó vì nó sử dụng khối 900 KB. XZ sử dụng LZMA, IIRC có từ điển 4 MB ở mức nén mặc định. 5) Định dạng Zip không sử dụng nén rắn nên sẽ không nén các tệp tương tự hoặc giống hệt nhau.
Có lẽ máy nén từ họ PAQ hoặc PPMD sẽ nén tốt hơn nhưng nếu bạn cần nén nhiều tệp hình ảnh tương tự thì bạn có thể xem xét 3 cách tiếp cận:
1) Lưu trữ hình ảnh không nén (với PNG -0 hoặc ở định dạng không nén) và nén bằng máy nén có từ điển lớn hoặc kích thước khối. (LZMA sẽ hoạt động tốt)
2) Một tùy chọn khác sẽ là giữ các bộ lọc nhưng loại bỏ nén Deflate khỏi các PNG. Điều đó có thể được thực hiện ví dụ với tiện ích ( AdvDef ). Sau đó, bạn nén các PNG không nén kết quả. Sau khi giải nén, bạn có thể giữ PNG không nén hoặc nén chúng lại bằng AdvDef (nhưng sẽ mất thời gian).
Bạn cần kiểm tra cả hai cách tiếp cận để xem nén nào nhiều nhất.
3) Tùy chọn cuối cùng sẽ là chuyển đổi hình ảnh png trong video, nén nó bằng máy nén video lossless như x264 lossless (đặc biệt chú ý sử dụng định dạng màu phù hợp) và sau đó trích xuất trích xuất các khung hình thành từng hình ảnh png riêng lẻ. Điều đó có thể được thực hiện với ffmpeg. Bạn cũng cần giữ ánh xạ giữa số khung và tên gốc.
Đó sẽ là cách tiếp cận phức tạp nhất nhưng nếu pngs là một phần của hoạt hình thì nó có thể hiệu quả nhất. Tuy nhiên, bạn sẽ cần một định dạng video hỗ trợ tính minh bạch nếu bạn cần.
Chỉnh sửa: Cũng có định dạng MNG nên nó không được sử dụng thường xuyên.