Générer des images PNG#

Voici une fonction bien pratique pour créer une image au format PNG. La valeur ajoutée ici, c’est qu’on utilise seulement du Python pur, sans passer par de module tierce.

Imports#

generer-image-png.py#
import random
import struct
import zlib
from pathlib import Path

La fonction#

generer-image-png.py#
def generate_random_png(filename: str = "", size: int = 0) -> bytes | None:
    """Generate a random PNG file.

    :param filename: The output file name. If None, returns picture content.
    :param size: The number of black pixels of the picture.
    :return mixed: None if given filename else bytes
    """

    size = max(1, size) if size else random.randint(1, 1024)  # noqa: S311

    pack = struct.pack

    def chunk(header: bytes, data: bytes) -> bytes:
        return pack(">I", len(data)) + header + data + pack(">I", zlib.crc32(header + data) & 0xFFFFFFFF)

    magic = pack(">8B", 137, 80, 78, 71, 13, 10, 26, 10)
    png_filter = pack(">B", 0)
    scanline = pack(f">{size * 3}B", *[0] * (size * 3))
    content = [png_filter + scanline for _ in range(size)]
    png = (
        magic
        + chunk(b"IHDR", pack(">2I5B", size, size, 8, 2, 0, 0, 0))
        + chunk(b"IDAT", zlib.compress(b"".join(content)))
        + chunk(b"IEND", b"")
    )

    if filename:
        Path(filename).write_bytes(png)
        return None

    return png

Validation#

Pour vérifier la validité des fichiers générés :

identify -quiet -ping -format '%m %w %h %z %[colorspace]' 'FILE.png'
# PNG 42 42 8 sRGB
pngfix 'FILE.png'
# IDAT OK  default 15 15 28 5334 FILE.png

📜 Historique#

2024-02-07

Déplacement de l’article depuis le blog.

2017-05-17

Le fichier généré contenait une erreur IDAT:_uncompressed_data_too_small.

Ajout des commandes de vérification.

2017-04-13

Premier jet.