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:
>>> from PIL import Image
>>> img = Image.open('firefox_i9MPoqCoYe_2.png')
>>> arr = img.split()
>>> arr[-1].show()
Le résultat:
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()
Ajouter un commentaire