1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
class colorateur(threading.Thread):
"""
Enregistre l'image en même temps que le calculateur rapide
"""
global fin, matrice
def __init__(self, demarrage, lecture, identifiant, chemin, type_ppm):
global fin, matrice
"""
L'avantage de ce thread est qu'il permet d'enregistrer la fractale en même temps qu'elle se calcule
Cela permet également à ne pas avoir à stocker d'énormes données dans la ramme
"""
threading.Thread.__init__(self)
self.fin = False #Devient True quand il faut mourir
self.demarrage = demarrage #Pour connaitre les modules de traitement d'image disponible
self.lecture = lecture #Pour avoir accès à la fonction rvb
self.identifiant = identifiant #Pour avoir accès à la bonne ligne
self.type_ppm = type_ppm #Le format d'image shouaité
self.chemin = chemin #Chemin d'accès à la base de donnée
self.dico = {} #On y met toutes les couleurs déjà calculées afin de ne pas faire la réévaluation
nom_image = str(self.identifiant)+os.path.basename(self.chemin).replace(".db",".ppm")#Le nom de l'image ressemble au nom de la base
while nom_image[:6].isdigit() == False: #Tant que les 6 premiers caractères ne sont pas que des chiffres
nom_image = "0"+nom_image #On ajoute un 0 devant
self.path_image_finale = os.path.join(os.path.dirname(self.chemin), nom_image)#Le path de l'image finale
self.path_image = os.path.join(os.getcwd(),nom_image)#Le path de l'image qui va être créée dans cet ordinateur (image intermédiaire)
self.reussi = False #Reste False tant que l'image n'est pas dans le bon dossier
def run(self):
global fin, matrice
if self.gestion_globale(self.type_ppm): #On a le choix entre P3 et P6, P6 est mieu mais plus capricieux
print("Enregistrement réussi!")
self.reussi = True
return True
print("Erreur de l'enregistrement")
return False
def gestion_calculage(self, formatage, fichier):
"""
permet de distribuer le boulot de chaque ligne
"""
global fin, matrice
t = self.lecture.lire_donnees(self.identifiant)
rvb = [str(t[1]), str(t[2]), str(t[3])]
while not(fin): #Tant que les calculs de l'image ne sont pas finis
if self.fin: return False #Si il faut s'arrétter, on arrète
if matrice == []: #Si il faut attendre le calculateur
time.sleep(0.1) #On fait une petite pause
continue #On recommence le test
ligne = [coul for coul in matrice[0]] #Récupération de la ligne suivante (on la copie en entière)
del matrice[0] #On la suprimme pour faire de la place en mémoire
for i, valeur in enumerate(ligne): #Pour chaque divergence
if not(valeur in self.dico): #Si la couleur n'a pas été calculée
self.dico[valeur] = [max(0,min(255,round(eval(rvb[j])))) for j,d in enumerate([valeur,valeur,valeur])]#On la calcule
ligne[i] = self.dico[valeur] #On remplace la divergence par le lien qui mène à la couleur
if formatage == "P3": #Si l'on est ppm pas optimisé
self.enregistrer_ligneP3(ligne, fichier) #On continue dans cette optique
else: #Si le format est un peu mieu
self.enregistrer_ligneP6(ligne, fichier) #On enregistre cette ligne
return True #Quand le ppm est enregistré, on quitte cette méthode
def enregistrer_ligneP3(self, ligne, fichier):
"""
Ajoute une ligne au fichier
"""
fichier = open(self.path_image, "a") #On ouvre le fichier en mode ajout
for coul in ligne:
for rvb in coul:
fichier.write(" "+str(rvb))
fichier.close()
return None
def enregistrer_ligneP6(self, ligne, fichier):
"""
Ajoute une ligne au fichier
"""
fichier = open(self.path_image, "ab")
for coul in ligne:
fichier.write(bytes(coul))
fichier.close()
return None
def converteur(self, formatage):
"""
Met l'image dans le bon dossier et la converti en jpg si possible
Se charge de la suppression de l'image source
Retourne True si tous c'est bien passé
"""
"""Conversion en jpg"""
print("Conversion de l'image...")
if convertir_image(self.path_image, self.demarrage): #On essai de convertir l'image
print(" Suppression du vieu fichier...") #Si on a réussi à la convertir en jpg
try: #On essai de supprimer l'encien fichier
os.remove(self.path_image) #On supprime le fichier ppm
print(" Ok") #La suppression est réussi
except: #Si on arrive pas à le supprimer
print(" Echec de suppression") #On avoue notre echec!
self.path_image = self.path_image.replace(".ppm",".jpg") #On met à jour le nom du fichier
self.path_image_finale = self.path_image_finale.replace(".ppm",".jpg") #Des 2 cotés
print(" Ok") #La conversion c'est bien passée
else: #Si la conversion est mauvaise
print(" Echec de conversion") #L'utilisateur est tenu au courant
"""Copier/coller"""
print("Déplacement de l'image...")
path_fichier = os.path.join(os.path.dirname(self.path_image_finale),"acces_rep.txt")
clef(path_fichier)
try:
shutil.copy(self.path_image, self.path_image_finale) #On copie/colle l'image
os.remove(self.path_image) #On supprime l'image de départ
print(" Déplacement réussi")
fin_clef(path_fichier)
return True #On quitte le colorateur
except: #Si tout à échoué
print(" Echec du déplacement")
fin_clef(path_fichier)
if os.path.exists(self.path_image_finale): #Si bien qu'il y ai eu des problème, l'image est bien présente dans le dossier final
return True #On considère que l'on peut passer à l'image suivante
return False #Si l'image n'est pas là ou il faut, on quitte tristement le colorateur
def gestion_globale(self, formatage):
"""
Ouvre le fichier, le rempli, le déplace au bon endroit
"""
global fin, matrice
print(" Enregistrement de la fractale...")
t = self.lecture.lire_systeme(self.identifiant) #On lit dans la base la hauteur et la largeur
largeur = t[6] #Récupération de la largeur de l'image
hauteur = t[7] #Récupération de la hauteur de l'image
if formatage == "P3": #Si il faut l'enregistrer en ASCII ou UTF-8 (ici c'est pareil!)
for i in range(0,2): #On fait au maximum 2 passages
try: #Ce que l'on va faire peut échouer si l'on a pas les droits d'écriture
fichier = open(self.path_image, "w") #On tente de créer le fichier qui porte l'image
fichier.write("P3\n"+str(largeur)+" "+str(hauteur)+"\n255") #On écrit l'entête
fichier.close()
break #On ne fait pas la deuxième boucle
except: #Si on a pas les droits d'écriture
self.path_image = os.path.join(os.path.dirname(os.path.dirname(self.path_image_finale)), os.path.basename(self.path_image))#On cré l'image dans le répertoire enfant de l'image finale
if i == 1:
print(" Erreur accès refusé!")
return False
elif formatage == "P6":
for i in range(0,2):
try:
fichier = open(self.path_image, "wb")
entete = "P6\n"+str(largeur)+" "+str(hauteur)+"\n255\n"
fichier.write(entete.encode(encoding="UTF-8")) #Le retour à la ligne final est nécéssaire
fichier.close()
except:
self.path_image = os.path.join(os.path.dirname(os.path.dirname(self.path_image_finale)), os.path.basename(self.path_image))
if i == 1:
print(" Erreur accès refusé!")
return False
else:
print("Le formatage doit être 'P3' ou 'P6' mais pas",formatage)
return False
self.gestion_calculage(formatage, fichier) #On rempli l'image qui vient d'être créée
print(" Enregistrement terminé")
if self.fin: return False #Si on doit mourir, on se sucide de suite
return self.converteur(formatage) |