Định Dạng Đầu Ra Delta PNG

Nhận Khóa API

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:

Gốc

778×639 px

PNG thường

409.048 byte

Delta PNG

110.904 byte
Tiết kiệm 73%

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%

Giải mã Delta PNG

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.

Báo trước

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
Nhận Khóa API