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

Programmation multimédia/Jeux Python Discussion :

Fusion d'images (PIL ?)


Sujet :

Programmation multimédia/Jeux Python

  1. #1
    Futur Membre du Club
    Fusion d'images (PIL ?)
    Bonjour,

    J'aimerais pouvoir faire un programme pour automatiser la création de cartes pour un ami.

    Une des étapes consiste à insérer une image par dessus le fond, avec une fusion . (actuellement il le fait à la main avec Gimp ...)

    J'ai commencé ce week-end à découvrir PIL (Pillow ?) mais je n'ai pas réussi à avoir un résultat satisfaisant.
    Le mieux obtenu est avec un alpha_composite ... et j'ai galéré sans connaitre trop les images et couches alpha d'abord, et ensuite la lib PIL.

    Au final j'ai une sorte de fondu, mais tout est à moitié transparent en fait, et donc un résultat mitigé.

    Voici des sources et le rendu que j'aimerais avoir :
    * Le fond :


    * L'insert :


    * Le résultat gimp :



    Notes :
    - les sources sont en RGB sans couche alpha et fond transparent ...

    Voici un test effectué :
    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
     
    import os 
    from PIL import Image, ImageDraw, ImageFont 
    from utils import changeImageSize 
     
    #Test de blend (fusion) de 2 image avec un ratio alpha constant. 
    #Problème : cette fonction ne prend que 2 images de même taille ! 
     
    #Préparation du logo à insérer 
    filename='images/Dragon_Faerie_thumb.png' 
    logo = Image.open(filename, 'r') 
    logo = logo.convert("RGBA") 
    logo = changeImageSize(230, 230, logo) #Resize 
     
    #a_channel = Image.new('L', logo.size, 200)   # 'L' 8-bit pixels, black and white, +transparency 
    #logo.putalpha(a_channel) 
     
    #remplacement du blanc en transparent (fond + partout ...) 
    datas = logo.getdata() 
    newData = [] 
    for item in datas: 
        if item[0] > 240 and item[1] > 240 and item[2] > 240: 
            newData.append((0,0,0,0)) 
        else: 
            newData.append(item) 
    logo.putdata(newData) 
    logo.save("logo_temp.png") 
     
    #Préparation du background 
    filename1='images/FondCreature.png' 
    bg = Image.open(filename1, 'r') 
    bg = bg.convert("RGBA") 
     
    #Création masque foreground taille identique 
    fg = Image.new("RGBA", bg.size, (0,0,0,0)) 
    fg.paste(logo, (95,25), logo) 
    fg.save("fg_temp.png") 
     
    #Blend 
    blend_img = Image.alpha_composite(bg, fg) 
    blend_img.save("blend.png", format="png")


    * Résultat blend :


    ///

    J'ai testé une variante avec un masque alpha sur le "logo" et un Paste mais voici le résultat "paste/composite" :


    ///

    2 soucis à régler : le fondu
    * Blend : pas de fondu ?
    * Composite : fondu mais logo tout palot

    et supprimer le fond blanc car les sources ne sont pas correctes, sur le blend, on voir que le détourage est moyen.

    Merci d'avance pour votre aide
    dcpc

  2. #2
    Membre habitué
    Salut.

    Une petite piste avec ce module https://pypi.org/project/blend-modes/
    Il ne s'installe pas correctement chez moi avec la 3.6 de python, mais puisque ce module se compose d'un seul fichier, il suffit de se rendre sur le github https://github.com/flrs/blend_modes, et copier le fichier https://github.com/flrs/blend_modes/...blend_modes.py dans le répertoire de ton script pour utiliser ces fonctions et bien entendu numpy.

    Avec tes images et un script basique.

    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
    from PIL import Image
    import numpy
    import blend_modes
     
    bg = Image.open('./images/FondCreature.png').convert("RGBA")
     
    logo = Image.open('./images/Dragon_Faerie_thumb.png').convert("RGBA")
    w = 250
    h = int((w / bg.size[0]) * bg.size[1]) 
    logo = logo.resize((w, h))
     
    fg = Image.new('RGBA', bg.size)
    fg.paste(logo, (90, 15))
    #fg.save('./images/fg_temp.png')
     
    bg_array = numpy.array(bg).astype(float)
    fg_array = numpy.array(fg).astype(float)
     
    blended_array = blend_modes.multiply(bg_array, fg_array, 1.)
     
    img = Image.fromarray(numpy.uint8(blended_array))
    img.save('./images/blended.png')


    On arrive à une image comme



    Il y a encore un défaut avec les couleurs sombres du background, mais les fonctions de blend_modes renvoient à une page wikipédia expliquant comment sont calculées les combinaisons d'images selon le filtre utilisé. Peut-être que tu pourrais toi-même en fonction de l'opacité des pixels des deux images appliquer une combinaison différente, ou alors tenter une combinaison de plusieurs fonctions sur tes images.

    Bon courage.
    Le temps ronge l'amour comme l'acide.

  3. #3
    Futur Membre du Club
    HA merci, sympa, vais regarder ça, bon vais raojouter encore une source externe à ce petit projet mais bon

    Avec ce mode dois-je toujours essayer de retirer le fond blanc (tour et milieu) pour le passer en transparent ou pas ?

  4. #4
    Membre habitué
    Salut.

    Non, cela ne permet pas de rendre le blanc transparent, c'est le fait d'appliquer le multiply qui induit cela.

    Bon en fait, il y a déjà des effets disponibles dans PIL, voir le module ImageChops de pil, et pour un meilleur détourage de l'image, peut-être que le module ImageFilter pourrait convenir, mais là, je n'y connais absolument rien, et je ne sais si ça peut apporter une quelconque aide pour tes images.
    Le temps ronge l'amour comme l'acide.

  5. #5
    Futur Membre du Club
    Bon vais garder comme ça,

    J'ai testé un peu les autres modes et bof.

    Le multiply garde un peu trop de noir en effet, mais bon, ça peut le faire, et j'ai encore un tas de soucis à régler en fait, comme :
    - gérer le redimensionnement de l'illustration automatiquement quelle que soit la taille de la source
    - gérer son placement en auto avec un centrage dans une zone calculée
    - reprendre toute ma gestion de coordonnées (pour les textes que j'ajoute surtout) pour ne pas avoir "en dur" les coordonnées .... là vais avoir un fond en plus grande résolution (sinon impression c limite), je dois tout recalculer les placements :-(

    --> je vais ouvrir un autre sujet d'ailleurs pour ça voir si ya des idées ou techniques...
    (pis faut que je commence à remonter mes commits sur mon gitlab )

  6. #6
    Membre confirmé
    Codeurs > Infographistes
    Tant mieux si cette solution te satisfait mais je pense que tu as pris le problème par le mauvais bout. Est-ce que ça ne serait pas plutôt les illustrations qu'il faudrait revoir ? Elles ne sont pas bonnes puisque pour bien les intégrer aux cartes il faudrait qu'elles soient transparentes.

    Note :

  7. #7
    Futur Membre du Club
    Faudrait voir en effet pour pouvoir modifier ces sources ... mais vraiment longtemps que pas fait ça.

    Je dois me mettre à Gimp ou cyberlink photodirector

###raw>template_hook.ano_emploi###