Gif - Convertir en nuance de gris
Par Akh le jeudi, 22 octobre 2009, 09:02 - Lien permanent
On prend un fichier image gif couleur tout bête et pour une raison x on veut récupérer la palette de cette image à l'index de couleur prêt en nuances de gris !
Et bien c'est à priori impossible par le quidam
Bon ! Pour bien comprendre le problème il va falloir être un peu technique :
Le problème
Une image Gif couleur c'est quoi ?
- une en-tête ou header contenant la signature GIF et des informations sur la taille de l'image (taille 13 octets)
- une palette de couleur donnant pour les 256 valeurs possibles les composants Rouge, Vert & Bleu (chacun de 0 à 255) soir 768 octets
- l'image avec pour chaque pixel l'indice dans la palette permettant de récupérer les compsants RVB (RGB), comme l'indice est codé sur 1 octet on a 256 valeurs de 0 à 255, ce qui explique la palette de couleur de 256 valeurs décrite ci-dessus
Une image Gif en nuance de gris c'est quoi ?
- le même en-tête
- une palette qui ne sert plus à rien car,
- l'image avec pour chaque pixel non pas l'indice dans la palette mais la valeur des composants RVB, car comme on est en nuance de gris le Rouge, le Vert et le Bleu ont la même valeur qui varie toujours de 0 à 255
Ce que je veux moi !
- c'est recalculer la palette en convertissant chaque entrée RGB en sa nuance de gris soit trois fois la même valeur
Ce que je ne veux pas !
- c'est que l'on touche / modifie la valeur du pixel qui doit rester l'indice dans la palette
C'est tordu ? Non pas vraiment ! C'est comme ça ! Et aucun des logiciels que j'ai eu dans les pattes ne le permet, dingue non ?
Ma solution
La technique
- Aide toi et ... A ce niveau il n'y a plus que la programmation n'est-ce pas, donc ma solution va consister à recalculer la palette dans le fichier Gif, facile
Attention il y a gris et gris !
- C'est déjà à savoir tous les gris ne se valent pas !
- La moyenne des composants RGB ça ne le fait pas
- En fait pour que cela marche (si j'ai bien tout compris) il faudrait convertir en CMY et là la moyenne marcherait, enfin bref,
- La formule magique (trouvée sur le NeT, peut-être un peu pale) c'est :
- Gris = 0.2125 * Rouge + 0.7154 * Vert + 0.0721 * Bleu
Maintenant le langage
- Alors un peu pressé par le temps je ne me suis pas posé longtemps la question
- J'avais Python 2.5 sous la main avec son IDLE (Python GUI)
- C'est super simple, rapide et je pense clair ...
Le Script :
Im = open("Image.gif",'r+b')
ImDummy = Im.read(13)
ImPal = Im.read(256*3)
ImPal2 = ''
for i in range(255):
r, g, b = ord(ImPal[i*3]),ord(ImPal[i*3+1]),ord(ImPal[i*3+2])
gray = r * 0.2125 + g * 0.7154 + b * .0721
ImPal2 = ImPal2 + chr(gray) + chr(gray) + chr(gray)
Im.seek(13)
Im.write(ImPal2)
Im.close()
Cela ne me servira certainement plus jamais et cela ne servira jamais à personne, mais bon c'est dit, c'est dit !
Commentaires
Bon j'ai oublié de préciser que cette manip n'est valable que pour les fichiers gif ne contenant qu'une seule image, pour les animations cela se complique un peu pour trouver la ou les palettes