IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Python Discussion :

création d'un ppm [Python 3.X]


Sujet :

Python

  1. #1
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Par défaut création d'un ppm
    Bonjour à tous, je rencontre quelques problèmes en enregistrant une image ppm au format P6!
    Lorsque, je l'enregistre au format P3, je n'ai aucun souci mais quand il s'agit de choisir un format qui prend (3*4/3) 4 fois moins de place, il se passe n'importe quoi!
    Après avoir longuement cherché sur la toile, je n'ai trouvé aucun algorithme qui fonctionne! j'ai soit le message d'erreur suivant: TypeError: 'str' does not support the buffer interface ou bien il me crée une image comme celle que vous pouvez voir Nom : image_fractale.jpg
Affichages : 1774
Taille : 71,5 Ko au lieu de me faire la bonne image (enregistrée en ppm P3):Nom : image_fractale_reussi.jpg
Affichages : 1705
Taille : 18,0 Ko .

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    fichier=open("image_fractale.ppm","w")
    fichier.write(str.encode("P6\n"+str(requeteur.largeur)+" "+str(requeteur.hauteur)+"\n255\n"))
    dico = {}
    for ligne in matrice:
    	for valeur in ligne:
    		if not(valeur in dico):
    			dico[valeur] = [max(0,min(255,round(eval(requeteur.rvb[i])))) for i,d in enumerate([valeur,valeur,valeur])]
    		for coul in dico[valeur]:
    			#fichier.write(struct.pack('B',coul))
    			fichier.write(chr(coul))
    fichier.close()
    La matrice est une liste de liste qui contient des nombres compris entre 0 et 1 selon la vitesse de la divergence de la suite.
    requeteur.rvb permet de transformer ces valeurs comprises entre 0 et 1 avec des entiers allant de 0 à 255. Par exemple, ici il vaut : ["255*(2**(-30*((d-1)**2)))","255*(2**(-40*((d-0.6)**2)))","160*(2**(-100*((d-0.3)**2)))"]. d étant la variable et chaque rang correspond à chaque couleur Rouge, Vert, Bleu.

    Lorsque je remplace la première ligne par: fichier=open("image_fractale.ppm","wb"), il me renvoi une erreur!

    Help, quelqu'un aurait-il une idée de la syntaxe à adopter? Merci!

  2. #2
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Salut,

    Citation Envoyé par Robin Richard Voir le message
    Help, quelqu'un aurait-il une idée de la syntaxe à adopter? Merci!
    Un problème de syntaxe se traduirait par une exception de type SyntaxError.
    Pour écrire des octets/bytes, vous n'avez pas le choix: il faut ouvrir le fichier en mode "binaire" ("wb") et y écrire des "bytes". Donc la question devient: comment "convertir" une liste de 3 entiers dans 0..255 en "bytes" ? Une solution parmi d'autres:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    >>> bytes([1, 2, 3])
    b'\x01\x02\x03'
    >>>
    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  3. #3
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Par défaut
    Merci pour votre réponse, cela permet de remplir le corps de l'image mais qu'en est-il de l'entête? Comment je peut faire pour enregistrer le "P6\nlargeur hauteur\n255" qui est au début?
    Et aussi, la fonction bytes() renvoi des octet complets ou ne renvoi que le nombre de bits nécessaire à la constitution du nombre entier?

  4. #4
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par Robin Richard Voir le message
    Comment je peut faire pour enregistrer le "P6\nlargeur hauteur\n255" qui est au début?
    .encode est assez bien, non?

    Citation Envoyé par Robin Richard Voir le message
    Et aussi, la fonction bytes() renvoi des octet complets ou ne renvoi que le nombre de bits nécessaire à la constitution du nombre entier?
    Un byte == un octet.
    Mais vous êtes supposé lire la documentation pour comprendre ce que çà fait avant de l'utiliser et pas juste recopier le code qu'on vous a suggéré dans un forum.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  5. #5
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Par défaut
    Bonjour, j'ai regardé la doc afin de ne pas avoir d'erreur mais bien qu'il ne montre aucun problème en apparence, il y a tout de même un pépin: L'image finale est un écran noir! (pourtant, elle prend de la place en mémoire)
    voici le code:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    for i in range(0,2):
    	try:
    		fichier = open(self.path_image, "wb")
    		entete = "P6\n"+str(self.requeteur.largeur)+" "+str(self.requeteur.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
    et puis, plus loin, cette fonction est appelée pour chaque ligne

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    fichier = open(self.path_image, "ab")
    for coul in ligne:
    	for rvb in coul:
    		fichier.write(bytes(rvb))
    fichier.close()
    return None
    Merci encore pour votre aide!

  6. #6
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Salut,

    Citation Envoyé par Robin Richard Voir le message
    L'image finale est un écran noir! (pourtant, elle prend de la place en mémoire)
    Le noir s'obtient avec r, v, b = 0, 0, 0.
    Si c'est ce qui a été écrit dans le fichier, ce serait cohérent. Mais on ne va pas regarder ce qu'il contient à votre place ni faire un "print" des bytes qui y sont écrits pour voir ce qu'ils sont.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  7. #7
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Par défaut
    J'ai fait un print de la variable rvb (de type int (ça n'est pas un tuple)), et on peut bien voir qu'elle ne contient pas que des 0! Par contre, une fois l'image terminée, je l'ai ouverte avec Sublime Text en hexadécimale et mis à part l'entête, il n'y avait que des 0! Comment se fait-il qu'il enregistre des 0 alors que 'rvb' ne vaut pas systématiquement 0?

  8. #8
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par Robin Richard Voir le message
    et mis à part l'entête, il n'y avait que des 0! Comment se fait-il qu'il enregistre des 0 alors que 'rvb' ne vaut pas systématiquement 0?
    Parce que vous n'avez pas bien lu la documentation de bytes qui explique que son comportement diffère suivant qu'on passe un entier ou une liste d'entiers...

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  9. #9
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Par défaut
    Super, cela fonctionne à merveille!
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
    fichier = open(self.path_image, "ab")
    for coul in ligne:
    	fichier.write(bytes(coul))
    fichier.close()
    return None
    Merci pour votre aide!

  10. #10
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par Robin Richard Voir le message
    Super, cela fonctionne à merveille!
    Il vous reste à appuyer sur le bouton

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  11. #11
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Par défaut C'est mieux qu'avant mais pas top!
    Me revoilà, finalement ce n'est pas terrible, même si cela semble fonctionner, Voila ce que me dit ImageMagick lorsque l'enregistrement se fait en P3:
    convert.im6: Fin de fichier inattendue `/home/robin/Programmes/Python/en_cours/000016fractale.ppm' @ error/pnm.c/ReadPNMImage/1252.

    Et pire encore, lorsque je l'enregistre en P6:
    convert.im6: pas d'images définies `/home/robin/Programmes/Python/en_cours/000018fractale.jpg' @ error/convert.c/ConvertImageCommand/3044.

    Pourtant, dans les 2 cas, les images sont parfaitement lisibles! (en tout cas leur miniature apparaît).

    Je vais vous mettre le minimum de code qui englobe tout:

    1: le programme principal:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    if __name__ == '__main__':															#Puisque l'on utilise Plusieurs coeurs, il ne faut pas faire de récursion infinies
     
    	"""interaction avec l'utilisateur"""
    	demarrage = demarreur(affichage=affichage)										#On cré le démarreur qui recherche les bases et les modules
    	demarrage.start()																#On le lance en arrière plan pour ne pas bloquer la suite des opérations
    	fenetre = tkinter.Tk()															#Création de la fenètre principale
    	affichage = afficheur(fenetre, demarrage)										#Remplissage de la fenêtre et interaction avec l'utilisateur
    	attente = attendeur(demarrage, affichage)										#Création de ce qui reste en eveil d'un signe du démarreur
    	attente.start()																	#Lancement en arrière plan de l'attendeur
    	fenetre.mainloop()																#Affichage de la fenêtre d'intéraction
    	fenetre.destroy()																#Fermeture définitive de la fenètre (il se passe toujours des choses bizard quand c'est dans un objet)
     
    	"""création de l'image"""
    	if attente.chemin != "":														#Si il faut aider une base de données
    		if not(os.path.isdir(os.getcwd())):											#Si le repertoir courant n'est pas une dossier
    			os.chdir(os.path.dirname(os.getcwd()))									#On fait en sorte que ça le soit
    		lecture = lecteur(attente.chemin)											#Création de l'objet qui permet de dialoguer avec la base de données
    		verificateur = verifier_base(attente.chemin,demarrage)						#Permet de vérifier la cohérence entre la base de données et les images présentes
    		verificateur.start()														#On lance sans plus attendre le vérificateur
    		emettage = emetteur(os.path.dirname(attente.chemin))						#Permet de montrer à tous le monde que l'on est actif
    		emettage.start()															#On le lance sans plus attendre
    		identifiant = 1																#C'est l'identifiant de la ligne à aider (arbitraire pour le moment)
    		while identifiant > 0:														#Tant qu'il y a une image à créer
    			clef(verificateur.path_fichier_base)									#On bloque l'accès à la base
    			identifiant = aider_base(attente.chemin, vite=True)						#On relève le vrai numéro de l'image à secourir (vite=True car on a déjà vérouillé l'accès)													#On refait le test
    			if identifiant > 0:														#Par contre, si il y a bel et bien une base à aider
    				emettage.id = identifiant											#On se fait passer pour la bonne personne
    				lecture.verouiller(identifiant, vite=True)							#On dit que l'image est en cours de création
    				fin_clef(verificateur.path_fichier_base)							#Il nous est désormait possible de libérer l'accès à la base de données
    				print("Aide pour l'image n°"+str(identifiant))						#On dit à l'utilisateur quelle image est en cours de traitement
    				matrice = []														#Création d'une variable globale qui contient la valeur de la divergence des pxls
    				fin = False															#Création d'une deuxième variable globale qui devient True quand le calcul de l'image est fini
    				coloriage = colorateur(demarrage,lecture,identifiant,attente.chemin,type_ppm)#Création du colorateur qui exploite la matrice
    				coloriage.start()													#Lancement du colorateur
    				communicage = communicateur(os.path.dirname(attente.chemin),verificateur,emettage,coloriage)#Pour pouvoir quitter le programme
    				communicage.start()													#Lancement du communicateur
    				calculage_rapide(identifiant,lecture)								#Lancement du calcul de la fractale
    				while coloriage.is_alive():											#Tant que le colorateur travail
    					continue														#On attend que ça méthode 'run' soit terminée
     
    			else:																	#Si il n'y a plus d'image à aider
    				fin_clef(verificateur.path_fichier_base)							#On libère l'accès à la base
    			if not(verificateur.boucle):											#Si l'on a pas encore verifié que toutes le images sont présentes
    				time.sleep(10)
    				identifiant = 1														#On refait un tour
    		verificateur.fin = True														#On assassine le verificateur
    		emettage.fin = True															#On assassine l'emetteur
    2: La fonction qui calcule l'image:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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
     
    def calculage_rapide(identifiant, lecture):
    	"""
            iters_max, mod_carre, largeur, hauteur, z0, suite, xmin, xmax, ymin, ymax, iteration, nbr_couleurs
            Rempli peu a peu la variable 'matrice'
            iters_max = nbr maximum d'itérations
            mod_carre = module maximum du nbr complex
            largeur = largeur de la matrice
            hauteur = hauteur de la marice
            z0 = premier terme de la suite
            suite = formule de récurence de la suite
            couleur = information que l'on enregistre dans la matrice
            xmin, xmax, ymin et ymax = dimension du plan complex
            iteration = True quand les itérations comptent et pas seulement le module
            nbr_couleur = Nombre totale de couleur différentes que peut avoir la fractale
            """
    	def calcul(ligne, hauteur):
    		"""
                    Remplissage d'une partie de la matrice
                    Retourne la ligne dans une liste
                    """
    		print("	Ligne n°"+str(ligne+1)+"----"+str(int(100*ligne/hauteur))+"%")
    		liste = []
    		i = j = complex(0,1)											#Ainsi, i et j seront considérés comme des variables
    		y = (ymax-ymin)*ligne/(hauteur-1)+ymin							#La partie imaginaire du plan complex
    		for colone in range(0,largeur):									#Pour chaque case de chaque ligne
    			x = (xmax-xmin)*colone/(largeur-1)+xmin						#La partie réel du plan complex
    			z = eval(z0)												#Création du premier rang de la suite
    			c = 0														#Initialisation du compteur
    			while (c<iters_max) and (((z.real**2)+(z.imag**2))<mod_carre):#Tant qu'il n'y a aucune raison d'arrêter le calcul de la suite
    				c+=1													#Incrémentation du compteur
    				z = eval(suite)											#Calcul du rang suivant
    			if iteration:												#Si la divergence de la suite compte
    				c = c/iters_max											#On prend en compte le nombre d'itérations
    			else:														#Si le module de la suite compte
    				c = abs(z)/math.sqrt(mod_carre)							#Sinon, c'est le module de z qui est pris en compte
    			liste.append(int(c*nbr_couleurs)/nbr_couleurs)				#Ce pxl est ajouté à la ligne
    		return liste													#La ligne est la valeur de retour
     
    	global matrice,fin													#On fait en sorte que la matrice soit accéssible dans tous le programme
     
    	if __name__ == "__main__":											#Si le programme en cours d'execution est le programme principal
    		tuple1, tuple2 = lecture.lire_tout(identifiant)					#On récupère les données qui permettents de crééer l'image
    		iters_max = tuple1[5]
    		mod_carre = tuple1[6]
    		largeur = tuple2[6]
    		hauteur = tuple2[7]
    		z0 = str(tuple1[7])
    		suite = str(tuple1[8])
    		xmin = tuple1[9]
    		xmax = tuple1[10]
    		ymin = tuple1[11]
    		ymax = tuple1[12]
    		iteration = tuple1[13]
    		nbr_couleurs = tuple1[4]
     
    		try:															#Si il est possible de travailler avec plusieurs coeurs
    			import multiprocessing										#On importe le module
    			pool = multiprocessing.Pool()								#Il est possible de mettre en argument: processes=nbr_de_coeurs
    			liste_res = []												#Tous les résultats seront enregistrés ici
    			compteur = 0												#On met le compteur à 0
    			for ligne in range(0,hauteur):								#Pour chacune des lignes à traiter
    				if fin: return None										#Si il faut en finir, on s'arrète de suite
    				compteur += 1											#On incrémente le compteur
    				liste_res.append(pool.apply_async(calcul, args=(ligne, hauteur)))#On s'en charge
    				compteur = compteur%(hauteur//10)						#C'est le nombre de boucles pandant lesquelles la matrice n'est pas actualisée
    				if compteur == 0:										#Si on en est à la 16ème boucle
    					pool.close()										#On arrète momentanément de charger la liste d'attente
    					pool.join()											#On lance les calculs en liste d'attente
    					matrice.extend([resultat.get() for resultat in liste_res])#Récupération des lignes qui viennent d'être calculées
    					pool = multiprocessing.Pool()						#On réinitialise le pooleur
    					liste_res = []										#On vide la liste des lignes qui ont déjà étés calculées
    			pool.close()												#Validation des dernières lignes
    			pool.join()													#Lancement des derniers calculs
    			matrice.extend([resultat.get() for resultat in liste_res])	#Récupération des derniers résultats
    		except:															#Sinon, si le multiprocesseurage n'a rien donné
    			for ligne in range(0,hauteur):								#Pour chaque ligne
    				matrice.append(calcul(ligne, hauteur))					#On la calcule et on l'ajoute à la matrice avant de passer à la suivante
    				if fin: return None										#Si il faut en finir, on s'arrète brusquement
    		fin = True														#De façon à ce que le colorateur sache que c'est fini
    		print("		Fin du calcul")
    		return None
    3: Enfin, le plus important (je pense), ce qui enregistre l'image à proprement parler:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    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)
    Je pense que cela suffit à voir d'ou peut provenir l'erreur. Je ne peux pas vous mettre le programme en pièce jointe car je l'ai trop commenté, il prend donc trop de place!
    Sans même avoir une idée précise de la source de l'erreur, je suis preneur de toutes les pistes! Merci

  12. #12
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par Robin Richard Voir le message
    Me revoilà, finalement ce n'est pas terrible, même si cela semble fonctionner, Voila ce que me dit ImageMagick lorsque l'enregistrement se fait en P3:
    convert.im6: Fin de fichier inattendue `/home/robin/Programmes/Python/en_cours/000016fractale.ppm' @ error/pnm.c/ReadPNMImage/1252.
    Si ImageMagick vous dit que le fichier ne contient pas assez d'informations, commencer par vérifier ce qu'il en est... (ouvrir le fichier ppm, le lire, faire un split, compter le nombre d'items, le comparer à ce qu'il devrait être,...).

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  13. #13
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Par défaut
    Effectivement, il manque une, deux voir 3 lignes à la fin selon le moment ou on exécute le scripte.
    Comment se fait-il qu'il manque des lignes? Et ce, de façon aléatoire?

  14. #14
    Expert éminent
    Homme Profil pro
    Architecte technique retraité
    Inscrit en
    Juin 2008
    Messages
    21 790
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Manche (Basse Normandie)

    Informations professionnelles :
    Activité : Architecte technique retraité
    Secteur : Industrie

    Informations forums :
    Inscription : Juin 2008
    Messages : 21 790
    Par défaut
    Citation Envoyé par Robin Richard Voir le message
    Effectivement, il manque une, deux voir 3 lignes à la fin selon le moment ou on exécute le scripte.
    Comment se fait-il qu'il manque des lignes? Et ce, de façon aléatoire?
    C'est le résultat du code que vous avez écrit. S'il y a un défaut, il faut le relire, comprendre ce qu'il fait,... et en ré-écrire des bouts pour corriger.

    - W
    Architectures post-modernes.
    Python sur DVP c'est aussi des FAQs, des cours et tutoriels

  15. #15
    Membre averti
    Homme Profil pro
    Étudiant
    Inscrit en
    Août 2017
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 26
    Localisation : France, Isère (Rhône Alpes)

    Informations professionnelles :
    Activité : Étudiant
    Secteur : Industrie

    Informations forums :
    Inscription : Août 2017
    Messages : 22
    Par défaut
    Cela est en partie résolu. Je dis en partie car j'ai localisé les 2 problèmes et je n'ai pu en corriger qu'un des 2. Désormais les 2 premières images créées sont toujours correctes mais le problème revient à la troisième image. Cela est du à un problème de cœur. Mais pour cela mérite d'être traité sur un autre sujet!
    En tous cas, merci, cela faisait des semaines que je me traînais ce problème et ce forum à bien fait avancer les choses !

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Classe pour la création d'un graphe xy
    Par Bob dans le forum MFC
    Réponses: 24
    Dernier message: 03/12/2009, 18h20
  2. Création dynamique de TImages
    Par Dric dans le forum C++Builder
    Réponses: 10
    Dernier message: 08/07/2002, 13h36
  3. [Kylix] Création d'un fichier lien
    Par DrQ dans le forum EDI
    Réponses: 2
    Dernier message: 14/05/2002, 22h30
  4. Création image BMP
    Par Anonymous dans le forum C
    Réponses: 2
    Dernier message: 25/04/2002, 17h04

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo