Python: Inverser le contraste d'une image PNG

Python fournit tout un tas de modules complémentaires pour tous les domaines mêmes les plus improbables.

PIL est un module Python qui permet de travailler sur tous les types d'images.

L'astuce suivante permet d'afficher l'image avec le contraste inversé en seulement quatre lignes de script Python.

Tous les tests sont réalisés avec cette image:

olivier

>>> from PIL import Image
>>> img = Image.open('firefox_i9MPoqCoYe_2.png')
>>> arr = img.split()
>>> arr[-1].show()

Le résultat:

olivier

Comment ça marche ?

En règle générale le format PNG contient 4 canaux, les 3 canaux principaux "RGB" et un canal supplémentaire "A" pour la translucidité.

Grâce à la méthode split, on récupère un tuple contenant tous les canaux séparément.

>>> print(arr)
(<PIL.Image.Image image mode=L size=351x330 at 0x789953440550>, <PIL.Image.Image image mode=L size=351x330 at 0x7899545902E0>, <PIL.Image.Image image mode=L size=351x330 at 0x789954A7F4C0>, <PIL.Image.Image image mode=L size=351x330 at 0x789954A7FEB0>)

La commande précédente montre les canaux disponibles, 4 au total.

Si on affiche le contenu des canaux grâce au module numpy

>>> import numpy as np
>>> np.array(img)
array([[[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ...,
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]],

       [[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ...,
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]],

       [[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ...,
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]],

       ...,

       [[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ...,
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]],

       [[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ...,
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]],

       [[255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        ...,
        [255, 255, 255,   0],
        [255, 255, 255,   0],
        [255, 255, 255,   0]]], dtype=uint8)

La différence entre les 3 premiers canaux "RGB" et le quatrième "A" est flagrante.

Si toutefois l'image ne contient pas de canal "A", il  est possible d'obtenir le même résultat en agissant sur le troisième canal, le "B".

>>> arr[2].point(lambda x: (256-x)**2).show()

olivier

 

Ajouter un commentaire

Filtered HTML

  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Tags HTML autorisés : <a> <em> <strong> <cite> <blockquote> <code> <ul> <ol> <li> <dl> <dt> <dd>
  • Les lignes et les paragraphes vont à la ligne automatiquement.

Plain text

  • Aucune balise HTML autorisée.
  • Les adresses de pages web et de messagerie électronique sont transformées en liens automatiquement.
  • Les lignes et les paragraphes vont à la ligne automatiquement.
CAPTCHA
Cette question permet de s'assurer que vous êtes un utilisateur humain et non un logiciel automatisé de pollupostage.
CAPTCHA visuel
Entrez les caractères (sans espace) affichés dans l'image.