Chuyển từ nhà cung cấp khác? Check out our migration guide
Định dạng đầu ra Delta PNG có thể tiết kiệm nhiều độ trễ và băng thông, và đặc biết có ích trong các trường hợp khẩn cấp về băng thông & độ trễ như các ứng dụng điện thoại di động.
Cần tải các pixel trong ảnh gốc cho khách hàng, và rồi sử dụng Delta PNG cho ảnh gốc để tạo ra ảnh kết quả.
Hình mẫu:
Ngay cả trong hình mẫu tập trung vào tóc này (là trường hợp ca tệ nhất cho định dạng Delta PNG), tiết kiệm rất nhiều: 73%
Delta PNG chỉ là tập tin PNG thông thường và có thể được đọc bằng bất kỳ thư viện phần mềm nào có khả năng đọc PNG. Sự khác biệt duy nhất được so sánh với kết quả PNG thông thường là chính các giá trị pixel. Ảnh nền được mã hóa đen trong suốt 0x00000000
và cận cảnh là màu trắng trong suốt 0x00FFFFFF
. Các pixel trong suốt một phần có các giá trị màu sắc thực của chúng.
Loại Pixel | Gốc | PNG thường | Delta PNG | Bộ Nguồn Đầu Ra |
---|---|---|---|---|
Mặt Trước |
0xFFrrggbb
|
0xFFrrggbb
|
0x00FFFFFF
|
Gốc |
Hình Nền |
0xFFrrggbb
|
0x00000000
|
0x00000000
|
Delta PNG |
Cạnh |
0xFFrrggbb
|
0x80rrggbb
|
0x80rrggbb
|
Delta PNG |
Việc này có nghĩa là khi bạn đang giải mã giá trị pixel Delta PNG, bạn cần phải kéo giá trị pixel thực từ Gốc khi bạn gặp phải màu trắng trong suốt 0x00FFFFFF
. Các pixel khác có cùng giá trị như trong định dạng PNG thông thường.
Đây là hình mẫu mã hóa TypeScrip để giải mã định dạng Delta PNG:
export function decodeDeltaPngInPlace(originalPixels: Uint8Array, deltaPngPixels: Uint8Array): Uint8Array { const N = originalPixels.length / 4; // Array of RGBA values, div 4 to get number of pixels for (let i = 0; i < N; i++) { const i4 = i * 4; const alpha = deltaPngPixels[i4 + 3]; // JavaScript is RGBA, +3 to get alpha if (alpha == 0) { const r = deltaPngPixels[i4]; // JavaScript is RGBA, +0 to get red if (r == 0xFF) { // Transparent white => foreground => take values from original deltaPngPixels[i4] = originalPixels[i4]; deltaPngPixels[i4 + 1] = originalPixels[i4 + 1]; deltaPngPixels[i4 + 2] = originalPixels[i4 + 2]; deltaPngPixels[i4 + 3] = originalPixels[i4 + 3]; } // else transparent black => background => keep values } // else partially transparent => keep values } return deltaPngPixels; }
Để biết thêm hoạt động về dự liệu pixel và hình ảnh trong JavaScript, hãy xem thao tác Pixel hoàn hảo với hướng dẫn canvas trên Mạng Mozilla Developer.
Thư viện tải hình ảnh của bạn phải có khả năng lưu giữ các giá trị pixel ngay cả đối với các pixel hoàn toàn trong suốt, đó là cách nó hoạt động bình thường.
Tuy nhiên, nếu bạn đang sử dụng, chẳng hạn như thư viện OpenCV nổi tiếng và Python, vậy thì bạn cần phải sử dụng cờ cv2.IMREAD_UNCHANGED
và tải hình ảnh như thế: cv2.imread(path, cv2.IMREAD_UNCHANGED)
. Mặt khác OpenCV làm hỏng các giá trị pixel thực sự của các pixel hoàn toàn trong suốt.
Đáng tiếc OpenCV không sử dụng thông tin luân phiên nào được lưu giữ trong hình ảnh khi bạn sử dụng cờ đó. Đây là lý do tại sao chúng tôi trả về đầu trang X-Input-Orientation
để cho bạn có thể sử dụng định hướng đúng cho hình ảnh trong trường hợp này.
Đây là hình mẫu mã hóa Python_OpenCV để dùng định hướng.
def apply_exif_rotation(im: np.ndarray, orientation: int) -> np.ndarray: # https://note.nkmk.me/en/python-opencv-numpy-rotate-flip/ if 1 < orientation <= 8: if 2 == orientation: # TOP-RIGHT, flip left-right, [1, 1] -> [-1, 1] im = cv2.flip(im, 1) elif 3 == orientation: # BOTTOM-RIGHT, rotate 180 im = cv2.rotate(im, cv2.ROTATE_180) elif 4 == orientation: # BOTTOM-LEFT, flip up-down, [1, 1] -> [1, -1] im = cv2.flip(im, 0) elif 5 == orientation: # LEFT-TOP, Rotate 90 and flip left-right im = cv2.rotate(im, cv2.ROTATE_90_CLOCKWISE) im = cv2.flip(im, 1) elif 6 == orientation: # RIGHT-TOP, Rotate 90 im = cv2.rotate(im, cv2.ROTATE_90_CLOCKWISE) elif 7 == orientation: # RIGHT-BOTTOM, im = cv2.rotate(im, cv2.ROTATE_90_CLOCKWISE) im = cv2.flip(im, 0) else: # 8 == orientation: # LEFT-BOTTOM, Rotate 270 im = cv2.rotate(im, cv2.ROTATE_90_COUNTERCLOCKWISE) return im