รูปแบบเอาต์พุต PNG เดลต้า

รับคีย์ API

คุณย้ายมาจากผู้ให้บริการอีกรายหนึ่งใช่หรือไม่ Check out our migration guide

รูปแบบเอาต์พุต PNG เดลต้าช่วยลดเวลาตอบสนองและประหยัดแบนด์วิดท์ได้มาก รวมทั้งมีประโยชน์อย่างยิ่งในสถานการณ์ที่เวลาตอบสนองและแบนด์วิธมีความสำคัญ เช่น แอปมือถือ

ทั้งนี้จะกำหนดให้โหลดพิกเซลในภาพต้นฉบับบนไคลเอนต์ จากนั้นจึงใช้ PNG เดลต้ากับภาพต้นฉบับเพื่อสร้างภาพที่เป็นผลลัพท์

ตัวอย่าง:

ภาพต้นฉบับ

778 × 639 พิกเซล

PNG ปกติ

409,048 ไบต์

PNG เดลต้า

110,904 ไบต์
ช่วยประหยัด 73%

แม้แต่ในตัวอย่างนี้ที่เน้นเส้นผมเป็นหลัก (ซึ่งเป็นสถานการณ์ที่เลวร้ายที่สุดสำหรับรูปแบบ PNG เดลต้า) ก็ยังช่วยประหยัดอย่างเห็นได้ชัด: 73%

การถอดรหัส PNG เดลต้า

PNG เดลต้าเป็นเพียงไฟล์ PNG ปกติที่คลังซอฟต์แวร์ใด ๆ ที่อ่าน PNG ได้จะสามารถอ่านไฟล์นี้ได้เช่นกัน เมื่อเปรียบเทียบกับภาพผลลัพธ์ PNG ปกติแล้ว สิ่งเดียวที่แตกต่างกันคือค่าพิกเซลเอง พื้นหลังได้รับการเข้ารหัสเป็นสีดำโปร่งใส 0x00000000 ส่วนพื้นหน้าเป็นสีขาวโปร่งใส 0x00FFFFFF พิกเซลโปร่งใสบางส่วนจะมีค่าสีตามจริง

ประเภทพิกเซล ภาพต้นฉบับ PNG ปกติ PNG เดลต้า แหล่งเอาต์พุต
พื้นหน้า 0xFFrrggbb 0xFFrrggbb 0x00FFFFFF ภาพต้นฉบับ
พื้นหลัง 0xFFrrggbb 0x00000000 0x00000000 PNG เดลต้า
ขอบ 0xFFrrggbb 0x80rrggbb 0x80rrggbb PNG เดลต้า

ทั้งนี้หมายความว่าเมื่อคุณถอดรหัสค่าพิกเซล PNG เดลต้า คุณจะต้องดึงค่าพิกเซลที่แท้จริงนั้นจากต้นฉบับเมื่อคุณพบสีขาวโปร่งใส 0x00FFFFFF พิกเซลอื่น ๆ มีค่าเดียวกันกับในรูปแบบ PNG ปกติ

นี่คือตัวอย่างรหัส TypeScript สำหรับการถอดรหัสรูปแบบ 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;
}

หากต้องการเรียนรู้เพิ่มเติมเกี่ยวกับการดำเนินการกับข้อมูลรูปภาพและข้อมูลพิกเซลใน JavaScript โปรดดูการช่วยสอนการจัดการพิกเซลกับแคนวาส ที่ยอดเยี่ยมบนเครือข่ายผู้พัฒนา Mozilla

คำเตือน

คลังการโหลดภาพของคุณจะต้องสามารถรักษาค่าพิกเซลไว้ได้แม้กระทั่งพิกเซลที่โปร่งใสทั้งหมด ซึ่งเป็นวิธีการทำงานตามปกติ

แต่หากคุณใช้คลัง อย่างเช่น Python และ OpenCV ที่รู้จักกันดี คุณจะต้องใช้สัญญาณเตือน cv2.IMREAD_UNCHANGED และโหลดภาพดังนี้: cv2.imread(path, cv2.IMREAD_UNCHANGED) มิฉะนั้น OpenCV จะลบล้างค่าพิกเซลที่แท้จริงของพิกเซลที่โปร่งใสทั้งหมด

ขออภัย OpenCV ไม่ได้ใช้ข้อมูลการหมุนใด ๆ ที่จัดเก็บไว้ในภาพเมื่อคุณใช้สัญญาณเตือนนั้น นี่คือเหตุผลที่เราส่งคืนส่วนหัวของ X-Input-Orientation เพื่อให้คุณสามารถใช้การวางทิศทางที่ถูกต้องกับภาพในสถานการณ์นี้

นี่คือตัวอย่างโค้ด Python+OpenCV เพื่อใช้ในการวางทิศทาง:

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
รับคีย์ API