Ascii Art [Résolu]

Signaler
-
jordane45
Messages postés
27556
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
16 février 2020
-
Bonsoir! J'ai un mini problème avec mon programme pour créer un Ascii Art à partir d'une image.
Je voudrais savoir comment régler ce problème et surtout savoir si mon programme présente un problème (même si je suis sûre qu'il y en a sinon je ne serai pas ici).
Je sais qu'il faut que je convertisse d'abord l'image en niveaux de gris (c'est fait) mais la partie la plus compliquée reste la suite, transformer un pixel en caractère Ascii. Et c'est là où je bloque. Il faut aussi que j'ouvre l'image en fichier texte mais, je suis également bloquée dessus.

Lorsque je lance ce programme, on m'affiche comme message d'erreur à la ligne 22: "list indices must be integers, not str"

Je pense que c'est le mieux que je puisse faire avec mes compétences actuelles.
from PIL import Image
 
imageAscii= Image.open("Capture.jpg")
largeur, hauteur=imageAscii.size
imageBut=Image .new( "RGB" , ( largeur , hauteur ) )
 
for i in range (hauteur):
    for j in range (largeur):
        p=imageAscii.getpixel((j,i))
        gris=int((p[0]+p[1]+p[2])/3)
        p=(gris,gris,gris)
        imageBut.putpixel((j,i),p)
 
ascii =['@','%','#','*','+','=',':','.',' ']
 
f=open("asciiTest.txt","w")
 
for x in range (hauteur):
    for y in range (largeur):
        p=imageAscii.getpixel((x,y))
        if 225<gris<255:
            print(ascii[' '])
        if 200<gris<225:
            print(ascii['.'])
        if 175<gris<200:
            print(ascii[':'])
        if 150<gris<175:
            print(ascii['='])
        if 125<gris<150:
            print(ascii['+'])
        if 100<gris<125:
            print(ascii['*'])
        if 75<gris<100:
            print(ascii['#'])
        if 25<gris<50:
            print(ascii['%'])
        if 0<gris<25:
            print(ascii['@'])
 
f.close()
imageBut.save("Test.jpg")
imageBut.show()


Merci d'avance pour votre aide ^^ (si vous voulez bien m'aider)

5 réponses

Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920
Bonjour,

Si on essaie de comprendre
- à partir de l'image originale tu crées une nouvelle image niveau de gris
- donc pour transformer en ascii, ce sont les pixels de la nouvelle image qu'il faudrait traiter, pas l'image originale
- et imagebut, c'est l'image niveau de gris, pour afficher l'ascii, c'est le fichier .txt qu'il faut afficher
jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920 > Lumina
en 22 soit
print(ascii[8])

soit, le tableau ascii ne servant à rien
print(' ')
et pareil pour tous les caractères

un programme sans erreur aura toujours plus de chance de donner un résultat qu'un programme contenant des erreurs ;-)
> jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020

Oui forcément ah ah...

J'ai d'ailleurs modifié mon programme mais je reçois un autre message d'erreur :

Traceback

<module>

getpixel

"IndexError: image Index out of range"

Pourriez vous peut-être m'aider à trouver l'erreur?

from PIL import Image

imageAscii= Image.open("Capture.jpg") #ouvrir image à modifier
largeur, hauteur=imageAscii.size #récupérer les dimensions de l'image
imageBut=Image .new( "RGB" , ( largeur , hauteur ) )

for i in range (hauteur):
for j in range (largeur):
p=imageAscii.getpixel((j,i))
gris=int((p[0]+p[1]+p[2])/3)
p=(gris,gris,gris)
imageBut.putpixel((j,i),p)


f=open("asciiTest.txt","r")

for x in range (hauteur):
for y in range (largeur):
p=imageBut.getpixel((x,y))
if 225<gris<255:
print(' ')
if 200<gris<225:
print('.')
if 175<gris<200:
print(':')
if 150<gris<175:
print('=')
if 125<gris<150:
print('+')
if 100<gris<125:
print('*')
if 75<gris<100:
print('#')
if 25<gris<50:
print('%')
if 0<gris<25:
print('@')
imageBut.save("Test.jpg")
f.close()
f.read()
jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920 > Lumina
Et toi tu penses quoi de l'erreur ? pour suivre il faut mettre des traces, des print pour avoir les valeurs des variables.

moi je vois soit getpixel c'est hauteur, largeur pas largeur, hauteur

ou range va de 0 à n-1, donc il faudrait hauteur-1
> jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020

Je vous avoue que je ne comprends pas très bien le message d'erreur de base. Mais sachant qu'il dit "out of range" cela doit venir de la boucle (je pense). Par contre, pourquoi mettre hauteur-1? Je ne comprends pas vraiment cela.
Ah et également il me dit 'getpixel' il doit y avoir une erreur venant de celui-ci mais je ne vois pas trop où. Excusez moi de poser autant de question par ailleurs ><'
jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920 > Lumina
out of range signifie en dehors des valeurs attendues

si c'est hauteur, largeur et que tu mets largeur, hauteur bien évidemment pour une image largeur 1024, hauteur 768 si tu demandes le pixel en hauteur 769, il n'existe pas ==> erreur

par ailleurs, sur les boucles ou tableaux, les indices peuvent commencer à 0 ou à 1, si c'est 1, pour une largeur de 1024, la fin est à 1024, mais si l'indice commence à zéro, la fin est en 1023 (1024 - 1) donc avec un indice qui commence à zéro, 1024 est une valeur en erreur
Ah d'accord! Je comprends mieux, merci! Donc il suffit que je rajoute -1 pour régler ce soucis. Je suppose que cela affecte également la largeur.

J'ai modifié et il marche enfin! Cependant, je n'ai toujours pas ce que je veux: Transformer un pixel au niveau de gris en un caractère Ascii.

from PIL import Image

imageAscii= Image.open("Capture.jpg")
hauteur, largeur =imageAscii.size
imageBut=Image.new( "RGB" , ( hauteur, largeur ) )

for i in range (hauteur-1):
    for j in range (largeur-1):
        p=imageAscii.getpixel((i,j))
        gris=int((p[0]+p[1]+p[2])/3)
        p=(gris,gris,gris)
        imageBut.putpixel((i,j),p)

ascii =['@','%','#','*','+','=',':','.',' ']

f=open("asciiTest.txt","r")

for x in range (hauteur):
    for y in range (largeur):
        p=imageBut.getpixel((x,y))
        if 225<gris<255:
         print(' ')
        if 200<gris<225:
            print('.')
        if 175<gris<200:
            print(':')
        if 150<gris<175:
            print('=')
        if 125<gris<150:
            print('+')
        if 100<gris<125:
            print('*')
        if 75<gris<100:
            print('#')
        if 25<gris<50:
            print('%')
        if 0<gris<25:
            print('@')

imageBut.save("Test.jpg")
f.close()


C'est possible que je vous embête encore un peu?

Le problème vient surement de la 2nd boucle mais, je ne sait pas trop quoi modifier pour qu'il me transforme ce pixel. (Ou tout effacer)
jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920
puis
 if 225<gris<255:
??? moi c'est la variable p que je testerais

et dans cette boucle, pareil pour le -1
> jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020

Normalement, oui, il contient l'image en niveau de gris. Lorsque je teste le programme, j'obtient une image en niveau de gris.
Concernant le fichier, normalement, puisque je suis sensée travailler avec des caractères, on m'a dit qu'il faut que j'ouvre un fichier .txt, mais j'avoue que je pense avoir mal introduit le fichier.

Je viens de remplacer gris pas p mais, Il m'indique comme message d'erreur : unorderable types int() tuple() pour
if 225<p<255:
jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920 > Lumina
fait un print de p pour voir ce qu'il contient

si c'est (x,x,x) il faut probablement mettre p(1) pour le test
> jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020

J'ai essayer de print( p ) et effectivement il me donne (252,252,252)
jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920 > Lumina
si on regarde la ligne 10, plutot p[1] pour le test, voire int(p[1])
Je pense être arrivé un quelque chose!

from PIL import Image

imageAscii= Image.open("Capture.jpg")
hauteur, largeur =imageAscii.size
imageBut=Image.new( "RGB" , ( hauteur, largeur ) )

for i in range (hauteur-1):
for j in range (largeur-1):
p=imageAscii.getpixel((i,j))
gris=int((p[0]+p[1]+p[2])/3)
p=(gris,gris,gris)
imageBut.putpixel((i,j),p)

for x in range (hauteur-1):
for y in range (largeur-1):
p=imageBut.getpixel((x,y))
if 225<p[0]<255:
print(' ')
if 200<p[0]<225:
print('.')
if 175<p[0]<200:
print(':')
if 150<p[1]<175:
print('=')
if 125<p[1]<150:
print('+')
if 100<p[1]<125:
print('*')
if 75<p[2]<100:
print('#')
if 25<p[2]<50:
print('%')
if 0<p[2]<25:
print('@')

imageBut.save("Test.jpg")


Cependant, les caractères apparaissent dans la console et si je regarde l'image que j'ai sauvegardé, ça reste une image en niveau de gris
jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920
l'image ascii doit être dans le fichier .txt, qu'il faut ouvrir et fermer

et pour écrire dans le fichier ;txt il faut au lieu du print faire f.write('*')

cf : https://python.doctor/page-lire-ecrire-creer-fichier-python
jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920
attention dans ton code il n'y a plus d'indentation

sur le forum pour spécifier que c'est un code python, il faut le sélectionner dans la liste à coté de
<>v
Luminamia
Messages postés
2
Date d'inscription
mercredi 5 février 2020
Statut
Membre
Dernière intervention
5 février 2020
> jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020

Ah oui, excusez moi.

Par contre, le fichier txt ne correspond pas à mon image. Je pense que c'est dû à la variable p qui contient (252,252,252)
from PIL import Image

imageAscii= Image.open("Capture.jpg")
hauteur, largeur =imageAscii.size
imageBut=Image.new( "RGB" , ( hauteur, largeur ) )

for i in range (hauteur-1):
    for j in range (largeur-1):
        p=imageAscii.getpixel((i,j))
        gris=int((p[0]+p[1]+p[2])/3)
        p=(gris,gris,gris)
        imageBut.putpixel((i,j),p)

f=open("AsciiTest.txt","w")

for x in range (hauteur-1):
    for y in range (largeur-1):
        p=imageBut.getpixel((x,y))
        if 225<p[0]<255:
            f.write(' ')
        if 200<p[0]<225:
            f.write('.')
        if 175<p[0]<200:
            f.write(':')
        if 150<p[1]<175:
            f.write('=')
        if 125<p[1]<150:
            f.write('+')
        if 100<p[1]<125:
            f.write('*')
        if 75<p[2]<100:
            f.write('#')
        if 25<p[2]<50:
            f.write('%')
        if 0<p[2]<25:
            f.write('@')

f.close()


(J'ai créé un compte afin de vous montrer les captures)

L'image que je veux transformer:


Ce que j'obtiens dans le fichier txt:

jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020
5 920 > Luminamia
Messages postés
2
Date d'inscription
mercredi 5 février 2020
Statut
Membre
Dernière intervention
5 février 2020

le soucis doit venir de ce qu'il n'y a pas de saut de ligne, tous les caractères sont mis bout à bout
il faudrait rajouter un saut de ligne en fin de boucle x

for x in range (hauteur-1):
    for y in range (largeur-1):
        p=imageBut.getpixel((x,y))
        if 225<p[0]<255:
            f.write(' ')
        if 200<p[0]<225:
            f.write('.')
......
        if 0<p[2]<25:
            f.write('@')
    f.write('\n')
Luminamia
Messages postés
2
Date d'inscription
mercredi 5 février 2020
Statut
Membre
Dernière intervention
5 février 2020
> jee pee
Messages postés
28092
Date d'inscription
mercredi 2 mai 2007
Statut
Modérateur
Dernière intervention
15 février 2020

Ouiii ça marche! Bon l'image est un peu trop grande donc je pense la scale un peu.

Mais de tout cœur merci infiniment d'avoir prêter un peu (beaucoup) de votre temps pour m'aider!

Encore merci!
Bonjour, est-ce possible de supprimer ce poste? J'ai essayé en appuyant sur le bouton signaler mais, le topic est toujours ici. Mon problème a été résolue donc je pense que l'on peut l'enlever.

Je sais qu'il faut laisser pour d'autre personne qui ont un problème similaire... mais si c'est pour faire du copie collé... ou est l'intérêt?
Messages postés
27556
Date d'inscription
mercredi 22 octobre 2003
Statut
Modérateur
Dernière intervention
16 février 2020
2 108
Bonjour,

Suite à ton signalement :

Étant donner que le sujet a été résolue... pourriez vous effacer le topic s'il vous plaît? Comme je l'ai explicitement signaler avant, je ne souhaite pas partager ce code afin qu'il soit recopier par d'autres personnes. Merci.

Non ! Il ne sera pas effacé.
Le principe du forum est que les personnes puissent aider à résoudre des soucis...... soucis que d'autres peuvent également rencontrer un jour.

Ca ne sert donc à rien de venir demander la suppression de ce message.


Je sais qu'il faut laisser pour d'autre personne qui ont un problème similaire... mais si c'est pour faire du copie collé... ou est l'intérêt?

L'intéret ? Que si d'autres personnes cherchent à résoudre le même souci que toi... qu'elles puissent trouver leur réponse sans qu'on ai besoin de refaire les mêmes explications.

Si on devait supprimer chaque message résolu pour éviter le "plagiat"... on n'en finirait pas de se répéter ( encore plus que maintenant... et c'est déjà assez casse pied comme ça )


Cordialement,
Jordane