Format de sortie Delta PNG

Obtenir la clé API

Vous migrez depuis un autre fournisseur ? Check out our migration guide

Le format de sortie Delta PNG permet d'économiser beaucoup de latence et de bande passante, et est particulièrement utile dans les scénarios critiques en matière de latence et de bande passante, comme les applications mobiles.

Cela nécessite que les pixels de l'image d'origine soient chargés sur le client, puis que le Delta PNG soit appliqué à l'image d'origine pour produire l'image résultante.

Exemple :

Original

778 × 639 px

PNG classique

409 048 octets

Delta PNG

110 904 octets
73 % d'économies.

Même dans cet exemple centré sur les cheveux (qui est le pire des cas pour le format Delta PNG), les économies sont significatives : 73 %

Décodage de Delta PNG

Un fichier Delta PNG est un fichier PNG ordinaire et peut être lu par n’importe quelle bibliothèque logicielle capable de lire les PNG. La seule différence par rapport à un résultat PNG classique réside dans les valeurs des pixels elles-mêmes. L'arrière-plan est codé en noir transparent 0x00000000 et le premier plan en blanc transparent 0x00FFFFFF. Les pixels partiellement transparents ont leurs valeurs de couleur réelles.

Type de pixels Original PNG classique Delta PNG Source de sortie
Avant-plan 0xFFrrggbb 0xFFrrggbb 0x00FFFFFF Original
Arrière-plan 0xFFrrggbb 0x00000000 0x00000000 Delta PNG
Bord 0xFFrrggbb 0x80rrggbb 0x80rrggbb Delta PNG

Cela signifie que lorsque vous décodez les valeurs de pixels Delta PNG, vous devez extraire la valeur réelle des pixels de l'original lorsque vous rencontrez un blanc transparent 0x00FFFFFF. Les autres pixels ont les mêmes valeurs que celles du format PNG classique.

Voici un exemple de code TypeScript pour décoder le format 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;
}

Pour en savoir plus sur l'utilisation des données d'image et de pixels en JavaScript, consultez l'excellent didacticiel Manipulation des pixels avec canevas sur le réseau de développeurs Mozilla.

Mises en garde

​ 824 / 5,000 Translation results Translation result Votre bibliothèque de chargement d'images doit être capable de conserver les valeurs des pixels même pour les pixels entièrement transparents, ce qui correspong au fonctionnement normal.

Cependant, si vous utilisez par ex. Python et la célèbre bibliothèque OpenCV, vous devez alors utiliser l'indicateur cv2.IMREAD_UNCHANGED et charger l'image comme ceci : cv2.imread(path, cv2.IMREAD_UNCHANGED). Sinon, OpenCV écrasera les valeurs réelles des pixels entièrement transparents.

Malheureusement, OpenCV n'applique aucune information de rotation stockée dans l'image lorsque vous utilisez cet indicateur. C'est pourquoi nous renvoyons l'en-tête X-Input-Orientation afin que vous puissiez appliquer la bonne orientation à l'image dans ce scénario.

Voici un exemple de code Python+OpenCV pour appliquer l'orientation :

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
Obtenir la clé API