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

Calcul scientifique Python Discussion :

Appliquer un masque avec PIL


Sujet :

Calcul scientifique Python

  1. #1
    Futur Membre du Club
    Inscrit en
    Août 2007
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 5
    Points : 5
    Points
    5
    Par défaut Appliquer un masque avec PIL
    Bonjour,

    Encore débutant en Python, je programme une petite application destinée à réaliser des cartes à partir de tableau. En fait, je cherche à appliquer simplement un masque sur un fond de carte. Je ne sais pas si c'est très clair: par exemple, à partir d'un fond de carte vierge des régions françaises, je veux une Île-de-France en bleu, une Aquitaine en rouge, une Alsace en brun... pour obtenir quelque chose comme ça (lien pris au hasard sur Google):


    Je vais faire ancien combattant, mais à l'époque ou je programmais en assembleur 68000 sur Amiga, j'aurais simplement collé l'image de la région que je veux colorier sur le fond de carte, avec la couleur d'arrière-plan transparente. En tout cas, je reprends l'idée.

    J'ai donc cherché, trouvé PIL et sa fonction paste.

    Pour tester, j'ai fait à partir du tutorial:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    # -*- coding: iso-8859-1 -*-
    import Image
    im = Image.open("P:\Personnel\BMP2GIF\FRANCE.GIF")
    region = Image.open("P:\Personnel\BMP2GIF\AQUITAINE.GIF")
     
    box=(0,0,151,177)
    im.paste(region,box)
    im.show()
    Tout bête, et ça marche, sauf qu'évidemment, le blanc autour de l'image de l'Aquitaine efface le fond de carte (quoiqu'il soit traité en 'transparent' sur l'image GIF.

    J'ai voulu essayer le paramètre de masque de 'paste', mais ça ne marche pas et je ne comprends pas le message d'erreur:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    >>> im.paste(region, box=box, mask=128)
    
    Traceback (most recent call last):
      File "<pyshell#23>", line 1, in <module>
        im.paste(region, box=box, mask=128)
      File "C:\Fichiers\Python\lib\site-packages\PIL\Image.py", line 1073, in paste
        mask.load()
    AttributeError: 'int' object has no attribute 'load'
    Y a-t-il un autre moyen ? Où une autre bibliothèque comme matplotlib (pas très compréhensible pour moi, d'ailleurs) ?
    Merci de vos réponses.
    Images attachées Images attachées  

  2. #2
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    Je ne sais plus pour le format gif, toutefois je sais que le format png gère les couches alpha, il te faudra donc tout d'abord editer ton image via The Gimp, Photoshop ou tout autre éditeur qui se respecte... le concapte d'une couche alpha est en fait une sorte de calque (en fait un channel, mais bon, ça reste l'esprit d'un calque) en niveaux de gris, si je me souvient bien, ce qui est noir sur ce canal, sera masqué...
    dans PIL les formats supportant les couches alpha auront comme modes possible en général "RGBA" (Red, Green, Blue, Alpha), "LA" (L? (bref, niveau de gris), Alpha), etc, etc...

    En fait, je t'ai conseillé d'éditer via un editeur parceque c'est plus facile, mais si tu as les connaissances suffisante pour détecter les contours et toutes les autre connaissances nécéssaire à la réalisation d'un algoritme te permettant de savoir si tel pixel de l'image (ou de la selection) soit transparent (valeur Alpha du pixel à 0 ), ce sera évidemment plus rapide de programmer cet algorythme et de le faire tourner sur chaques image/selections si ces dernières sont nombreuses...

    En ce qui concerne le message d'erreur, je crois que c'est parce que le paramètre mask doit être, d'après ce que j'ai compris, non pas une valeur, mais une image, si le format de l'image que tu colle possède une bande (un canal) Alpha, alors tu peux mettre comme mask la référence à ton image (si img=Image.open('./blabla.png'), alors img peut servir en tant que mask)
    Ou bien tout simplement utiliser une image en niveaux de gris comme mask

    im.paste(image, box, mask)

    Same as above, but updates only the regions indicated by the mask. You can use either "1", "L" or "RGBA" images (in the latter case, the alpha band is used as mask). Where the mask is 255, the given image is copied as is. Where the mask is 0, the current value is preserved. Intermediate values can be used for transparency effects.
    Note that if you paste an "RGBA" image, the alpha band is ignored. You can work around this by using the same image as both source image and mask.

  3. #3
    Futur Membre du Club
    Inscrit en
    Août 2007
    Messages
    5
    Détails du profil
    Informations forums :
    Inscription : Août 2007
    Messages : 5
    Points : 5
    Points
    5
    Par défaut
    Merci de ta sympathique réponse circonstanciée. Dommage que je n'aie pas les connaissances nécessaires pour la comprendre vraiment bien !

    Citation Envoyé par N.tox Voir le message
    mais si tu as les connaissances suffisante pour détecter les contours et toutes les autre connaissances nécéssaire à la réalisation d'un algoritme te permettant de savoir si tel pixel de l'image (ou de la selection) soit transparent (valeur Alpha du pixel à 0 ), ce sera évidemment plus rapide de programmer cet algorythme et de le faire tourner sur chaques image/selections si ces dernières sont nombreuses...
    Oui, alors, ce sera un éditeur, hein ...

    Citation Envoyé par N.tox Voir le message
    En ce qui concerne le message d'erreur, je crois que c'est parce que le paramètre mask doit être, d'après ce que j'ai compris, non pas une valeur, mais une image, si le format de l'image que tu colle possède une bande (un canal) Alpha, alors tu peux mettre comme mask la référence à ton image (si img=Image.open('./blabla.png'), alors img peut servir en tant que mask)
    Ou bien tout simplement utiliser une image en niveaux de gris comme mask
    J'ai donc essayé (avec du GIF comme avec du PNG):
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    # -*- coding: iso-8859-1 -*-
    import Image
    im = Image.open("P:\Personnel\BMP2GIF\Talence.bmp")
    region = Image.open("P:\Personnel\BMP2GIF\TEST.GIF")
    masque = Image.open("P:\Personnel\BMP2GIF\TEST.GIF")
    box=(0,0,151,177)
    im.paste(region,box,masque)
    im.show()
    Mais j'ai un message d'erreur:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    Traceback (most recent call last):
      File "C:/Fichiers/Python/Essai PIL.py", line 7, in <module>
        im.paste(region,box,masque)
      File "C:\Fichiers\Python\lib\site-packages\PIL\Image.py", line 1074, in paste
        self.im.paste(im, box, mask.im)
    ValueError: bad transparency mask
    Il semble qu'il n'aime pas trop une image comme masque !

  4. #4
    Rédacteur

    Avatar de Matthieu Brucher
    Profil pro
    Développeur HPC
    Inscrit en
    Juillet 2005
    Messages
    9 810
    Détails du profil
    Informations personnelles :
    Âge : 42
    Localisation : France, Pyrénées Atlantiques (Aquitaine)

    Informations professionnelles :
    Activité : Développeur HPC
    Secteur : Industrie

    Informations forums :
    Inscription : Juillet 2005
    Messages : 9 810
    Points : 20 970
    Points
    20 970
    Par défaut
    Un masque, c'est composé peut-être de 0 et de 1 pour lui. Vérifie.

  5. #5
    Membre éclairé
    Homme Profil pro
    heu...
    Inscrit en
    Octobre 2007
    Messages
    648
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : heu...

    Informations forums :
    Inscription : Octobre 2007
    Messages : 648
    Points : 773
    Points
    773
    Par défaut
    En fait, je crois que l'image qui sert de mask, dans le cas où tu te sert d'une image et d'un masque séparé (2 fichiers donc), doit être enregistré en niveaux de gris. Je précise au cas où, qu'il ne suffit pas d'utiliser du gris comme couleur pour avoir une image en niveaux de gris, il faut regler le mode colorimetrique explicitement en niveaux de gris...

    Par exemple sous Gimp et Photoshop, créer une nouvelle image ou en ouvrir une déjà existante puis, menu image > Mode > Niveaux de gris (ou Grayscale en anglais)

    Je viens de tester, et ça fonctionne

    donc, en résumé, l'image que tu colle est du mode que tu veux (RGB,RGBA,L,LA), et l'image qui sert de mask est quand à elle en 'vrai' niveaux de gris (L donc) et également de la même taille que l'image à coller. Enfin, l'image sur laquelle tu veux coller doit pouvoir gerer le canal alpha (pas vraiment sur de ça...)

    EDIT: je me suis repenché sur les formats supportants les couches alpha, apparemment, je me suis trompé: les formats gif et png gèrent tous deux la transparence, mais pas les couches alpha, les formats qui les supportent apparement sont bmp, tif et les formats propre aux éditeurs (psd etc...), encore qu'il faille pour certains d'entre eux leur préciser lors de l'enregistrement...

  6. #6
    Nouveau Candidat au Club
    Inscrit en
    Avril 2007
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Avril 2007
    Messages : 1
    Points : 1
    Points
    1
    Par défaut
    Voici la solution (la valeur 128 pour la transparence):

    mask = label.point(lambda i: 128)

    Aide : http://www.pythonware.com/library/pi...troduction.htm
    § Processing individual bands

    exemple :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                        label = Image.new("RGBA", labelsize)
                        draw = ImageDraw.Draw( label )
                        draw.text( (2,2), imgfileIn, fill="#000000" )
                        draw.text( (0,0), imgfileIn, fill="#FFFFFF" )
                        mask = label.point(lambda i: 128)
                        im2.paste( label, (0,0,), mask )

Discussions similaires

  1. Réponses: 43
    Dernier message: 03/03/2006, 19h41
  2. [D7] masque avec restriction de saisi de caractères
    Par raoulmania dans le forum Composants VCL
    Réponses: 5
    Dernier message: 13/12/2005, 07h41
  3. Réponses: 9
    Dernier message: 16/11/2005, 11h32
  4. Masque avec la valeur 1000
    Par la7su dans le forum C++
    Réponses: 5
    Dernier message: 14/10/2005, 10h54
  5. [JFormattedTextFiel] masque avec virgule flottante
    Par lilou77 dans le forum Composants
    Réponses: 2
    Dernier message: 15/09/2005, 11h55

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