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.Vous n'êtes pas autorisé à joindre un fichier à cette page.