Pièce jointe « pnm.py »

Téléchargement

   1 # encoding: utf-8
   2 
   3 # Création d'une image unie
   4 
   5 def creer_image_gris (largeur, hauteur, maximum):
   6     return {
   7             'format': 'gris',
   8             'largeur': largeur,
   9             'hauteur': hauteur,
  10             'maximum': maximum,
  11             'donnees': bytearray(largeur * hauteur)
  12         }
  13 
  14 def lire_pixel_gris (image, x, y):
  15     position = image['largeur'] * y + x
  16     return image['donnees'][position]
  17 
  18 def ecrire_pixel_gris (image, x, y, valeur):
  19     position = image['largeur'] * y + x
  20     image['donnees'][position] = valeur
  21 
  22 
  23 def creer_image_couleur (largeur, hauteur, maximum):
  24     return {
  25             'format': 'couleur',
  26             'largeur': largeur,
  27             'hauteur': hauteur,
  28             'maximum': maximum,
  29             'donnees': bytearray(largeur * hauteur * 3)
  30         }
  31 
  32 def lire_pixel_couleur (image, x, y):
  33     position = (image['largeur'] * y + x) * 3
  34     rouge = image['donnees'][position]
  35     vert = image['donnees'][position + 1]
  36     bleu = image['donnees'][position + 2]
  37     return rouge, vert, bleu
  38 
  39 def ecrire_pixel_couleur (image, x, y, rouge, vert, bleu):
  40     position = (image['largeur'] * y + x) * 3
  41     image['donnees'][position] = rouge
  42     image['donnees'][position + 1] = vert
  43     image['donnees'][position + 2] = bleu
  44 
  45 
  46 # Écriture d'une image en format PNM
  47 
  48 def ecrire_pbm_binaire (image, fichier):
  49     sortie = open(fichier, "wb")
  50     en_tete = "P3 %d %d\n" % (image['largeur'], image['hauteur'])
  51     sortie.write(en_tete.encode("ascii"))
  52     sortie.write(image['donnees'])
  53 
  54 def ecrire_pgm_binaire (image, fichier):
  55     sortie = open(fichier, "wb")
  56     en_tete = "P5 %d %d %d\n" % (image['largeur'], image['hauteur'], image['maximum'])
  57     sortie.write(en_tete.encode("ascii"))
  58     sortie.write(image['donnees'])
  59 
  60 def ecrire_ppm_binaire (image, fichier):
  61     sortie = open(fichier, "wb")
  62     en_tete = "P6 %d %d %d\n" % (image['largeur'], image['hauteur'], image['maximum'])
  63     sortie.write(en_tete.encode("ascii"))
  64     sortie.write(image['donnees'])
  65 
  66 
  67 # Lecture du prochain "mot" sur un fichier PNM
  68 #
  69 # le mot est composé de tous les octets qui suivent jusqu'au prochain octet
  70 # correspondant à un caractère d'espacement, lequel n'est pas conservé. Selon
  71 # la spécification du format PNM, un caractère '#' introduit un commentaire,
  72 # il est ignoré ainsi que tout ce qui le suit jusqu'au prochain retour à la
  73 # ligne.
  74 
  75 def lire_mot_pnm (entree):
  76     mot = b""
  77     while True:
  78         octet = entree.read(1)
  79 
  80         # Test de fin de fichier
  81 
  82         if len(octet) == 0:
  83             return mot
  84 
  85         # Test de fin de mot
  86 
  87         if octet in (b' ', b'\r', b'\n', b'\t'):
  88             if len(mot) != 0:
  89                 return mot
  90 
  91         # Traitement des commentaires
  92 
  93         if octet == b'#':
  94             entree.readline()
  95 
  96         else:
  97             mot += octet
  98 
  99 # Lecture d'un fichier image PNM
 100 #
 101 # Le format est déduit du premier mot du fichier.
 102 
 103 def lire_pnm (fichier):
 104     entree = open(fichier, "rb")
 105     forme = lire_mot_pnm(entree)
 106     if forme == b'P3':
 107         return lire_ppm_ascii(entree)
 108     elif forme == b'P4':
 109         return lire_pbm_binaire(entree)
 110     elif forme == b'P5':
 111         return lire_pgm_binaire(entree)
 112     elif forme == b'P6':
 113         return lire_ppm_binaire(entree)
 114     else:
 115         raise ValueError("Format inconnu: %s" % forme.encode('ASCII'))
 116 
 117 # Les fonctions suivantes servent à décoder un fichier image dont on connaît
 118 # le format: on suppose que le premier mot a déjà été lu et on lit la suite.
 119 
 120 # Format PBM binaire
 121 
 122 def lire_pbm_binaire (entree):
 123     largeur = int(lire_mot_pnm(entree))
 124     hauteur = int(lire_mot_pnm(entree))
 125     ligne = (largeur + 7) // 8
 126     donnees = bytearray(entree.read(ligne * hauteur))
 127     return {
 128             'format': 'bitmap',
 129             'largeur': largeur,
 130             'hauteur': hauteur,
 131             'ligne': ligne,
 132             'donnees': donnees
 133         }
 134 
 135 # Format PGM binaire
 136 
 137 def lire_pgm_binaire (entree):
 138     largeur = int(lire_mot_pnm(entree))
 139     hauteur = int(lire_mot_pnm(entree))
 140     maximum = int(lire_mot_pnm(entree))
 141     if maximum > 255:
 142         raise ValueError("Intervalle trop grand (%d)" % maximum)
 143     donnees = bytearray(entree.read(largeur * hauteur))
 144     return {
 145             'format': 'gris',
 146             'largeur': largeur,
 147             'hauteur': hauteur,
 148             'maximum': maximum,
 149             'donnees': donnees
 150         }
 151 
 152 # Format PPM binaire
 153 
 154 def lire_ppm_binaire (entree):
 155     largeur = int(lire_mot_pnm(entree))
 156     hauteur = int(lire_mot_pnm(entree))
 157     maximum = int(lire_mot_pnm(entree))
 158     if maximum > 255:
 159         raise ValueError("Intervalle trop grand (%d)" % maximum)
 160     donnees = bytearray(entree.read(largeur * hauteur * 3))
 161     return {
 162             'format': 'couleur',
 163             'largeur': largeur,
 164             'hauteur': hauteur,
 165             'maximum': maximum,
 166             'donnees': donnees
 167         }
 168 
 169 # Format PPM ascii
 170 
 171 def lire_ppm_ascii (entree):
 172     largeur = int(lire_mot_pnm(entree))
 173     hauteur = int(lire_mot_pnm(entree))
 174     maximum = int(lire_mot_pnm(entree))
 175     if maximum > 255:
 176         raise ValueError("Intervalle trop grand (%d)" % maximum)
 177     nombre = largeur * hauteur * 3
 178     donnees = bytearray(nombre)
 179     for i in range(nombre):
 180         mot = lire_mot_pnm(entree)
 181         donnees[i] = int(mot)
 182     return {
 183             'format': 'couleur',
 184             'largeur': largeur,
 185             'hauteur': hauteur,
 186             'maximum': maximum,
 187             'donnees': donnees
 188         }
 189 
 190 
 191 # Conversion de couleur vers gris
 192 
 193 def couleurs_vers_gris (entree):
 194     if entree['format'] != 'couleur':
 195         raise ValueError("l'image n'est pas en couleur")
 196     largeur = entree['largeur']
 197     hauteur = entree['hauteur']
 198     sortie = creer_image_gris(largeur, hauteur, entree['maximum'])
 199     for x in range(largeur):
 200         for y in range(hauteur):
 201             r, v, b = lire_pixel_couleur(entree, x, y)
 202             teinte = (r + v + b) // 3
 203             ecrire_pixel_gris(sortie, x, y, teinte)
 204     return sortie
 205 
 206 # Zoom d'un facteur arbitraire
 207 
 208 def zoom_gris (entree, facteur):
 209     if entree['format'] != 'gris':
 210         raise ValueError("l'image n'est pas en gris")
 211     largeur = int(entree['largeur'] * facteur)
 212     hauteur = int(entree['hauteur'] * facteur)
 213     sortie = creer_image_gris(largeur, hauteur, entree['maximum'])
 214     for x in range(largeur):
 215         for y in range(hauteur):
 216             teinte = lire_pixel_gris(entree, int(x/facteur), int(y/facteur))
 217             ecrire_pixel_gris(sortie, x, y, teinte)
 218     return sortie
 219 
 220 def test (largeur, hauteur):
 221     image = creer_image_gris(largeur, hauteur, 255)
 222     for x in range(largeur):
 223         for y in range(hauteur):
 224             teinte = ((x*x + y*y) // 20) % 256
 225             ecrire_pixel_gris(image, x, y, teinte)
 226     ecrire_pgm_binaire(image, "sortie.pgm")
 227 
 228 if __name__ == '__main__':
 229     i1 = lire_pnm("pinklady.ppm")
 230     i2 = couleurs_vers_gris(i1)
 231     i3 = zoom_gris(i2, 10)
 232     ecrire_pgm_binaire(i3, "sortie.pgm")

Fichiers joints

Pour vous référer aux pièces jointes d'une page, utilisez attachment:filename, comme indiqué ci-dessous dans la liste de fichiers. N'utilisez pas l'URL du lien [get], car elle peut changer et donc être facilement cassée.
 All files | Selected Files: delete move to page copy to page

Vous n'êtes pas autorisé à joindre un fichier à cette page.