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

Contribuez Discussion :

Fusionner 2 images en gérant l'opacité


Sujet :

Contribuez

  1. #1
    Membre chevronné Avatar de laurent30s
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 881
    Points : 1 771
    Points
    1 771
    Par défaut Fusionner 2 images en gérant l'opacité
    La problématique : comment fusionner 2 images en gérant l'opacité

    Il existe la fonction dCopieImage() qui permet de copier une image sur une autre, à l'endroit où on veut... problème, elle ne gère pas l'opacité...

    Il existe la fonction dFusionne() qui permet de copier une image sur un autre en gérant l'opacité... problème, on ne peut pas choisir l'endroit où on veut...

    Comment faire ?

    En opérant pixel par pixel et en utilisant la fonction dFond() qui permet de sélectionner une couleur avec son opacité.

    J'ai mis tout ça dans une procédure :

    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
    PROCEDURE Fusion_image(sImage1,sImage2,nPos_x,nPos_y,nOpacite,nCouleur_Transp,iImage_Fusionnee)
     
    Res_Dessin est un entier
    i,j,i_maxi,j_maxi sont des entiers
    Ma_Couleur est un entier
    Mon_Opacité est un entier = nOpacite * 2.55
     
    Largeur_IMG_a_copier est un entier = {sImage1}..Largeur
    Hauteur_IMG_a_copier est un entier = {sImage1}..Hauteur
     
    Position_x est un entier = nPos_x
    Position_y est un entier = nPos_y
     
    Res_Dessin =dDébutDessin({sImage2},dAvecOpacité)
     
    i_maxi = Hauteur_IMG_a_copier - 1
    j_maxi = Largeur_IMG_a_copier - 1
    POUR i = 1 A i_maxi
    	POUR j = 1 A j_maxi
    		Ma_Couleur=dPixelCouleur({sImage1},j,i)
    		// si pas transparent
    		SI Ma_Couleur <> nCouleur_Transp ALORS
    			dFond(Ma_Couleur,Null,Null,Mon_Opacité)
    			dRectangle(Position_x+j,Position_y+i,Position_x+j+1,Position_y+i+1)
    		FIN
    	FIN	
    FIN
     
    iImage_Fusionnee = {sImage2}
    exemple d'utilisation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    iMon_Image est une Image
    Fusion_image("IMG_1","IMG_2",SAI_x,SAI_y,SAI_PC_opacite,SAI_Coul_transp,iMon_Image)
    IMG_3 = iMon_Image
    Précisions :
    - L'image1 est copiée sur l'image2
    - l'opacité doit être donnée en %
    - la couleur de transparence peut être différente entre les images, c'est pour ça qu'il faut la préciser.
    - le dernier paramètre (iMon_Image) permet de pouvoir récupérer l'image fusionné

    Bonne utilisation
    Bon dev
    Laurent

    - C’est génial.
    - Non c’est bizarre.
    - Justement quand c’est simple y’a des milliers de réponses et quand c’est bizarre y’en a aucune.

  2. #2
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Bonjour,

    Parcourir des pixels en WLangage c'est long.

    Dans dCopieImage il y a l'option copieImage qui gère l'opacité.
    C'est une magouille de WinDev, car évidemment ça n'est pas une option de StretchBlt, et ça ne supporte ni le redimensionnement, ni les champs images dessinés par programmation.

    copieImage : Combine l'image source et l'image destination en utilisant les informations de transparence de l'image destination
    Permet par exemple d'incorporer un logo dans l'image destination.
    Remarque : La taille et la position dans la source ne sont pas prises en compte. La taille et la position de la destination ne sont pas prises en compte. Ce mode ne permet pas d'homothétie ou de zoom.
    Evidemment la doc contient une erreur, c'est plutôt les "infos de transparence" de l'image source qui sont "utilisées".
    Autre erreur : la position dans la destination est prise en compte. (donc on dessine où on veut)

    Autre possibilité : .NET.

    Sinon, depuis la version 17 il y a d'autres possibilités, avec le type Image notamment, et des fonctions comme dFusionne.

    Avec une fonction ne permettant pas de positionner l'image où on veut, il sera préférable de dessiner dans une image temporaire la zone d'intersection (une partie de l'image de fond, puis fusion avec l'image superposée), puis de dessiner le résultat dans l'image de destination avec un dCopieImage normal, plutôt que de travailler au pixel.

    PS. Je viens de comprendre qu'on parle de transparence binaire. Dans ce cas il y a une astuce avec un système de masque, ne nécessitant que 2 dCopieImage (un avec copieSrcEt et l'autre avec copieSrcPeint).

  3. #3
    Membre chevronné Avatar de laurent30s
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 881
    Points : 1 771
    Points
    1 771
    Par défaut
    Je me suis peut-être mal exprimé.

    La fonction dCopieImage avec l'option copieImage permet bien une copie qui respecte la transparence de l'image copié.
    Par contre elle ne permet pas de créer de la transparence y compris sur les zones non transparentes à l'origine.

    La fonction dFusionne permet de créer de la transparence sur l'ensemble de l'image (opacité). Ça marche très bien sur les zones non transparentes à l'origine, l'inconvénient c'est que l'opacité s'applique également sur les zones transparentes à l'origine (pour une image ronde on se retrouve avec un rectangle opaque... pas terrible)

    Si on utiliser conjointement dCopieImage et dFusionne sur une partie de l'image on se retrouve avec le même problème d'opacité y compris sur les zones transparentes

    J'ai essayé dCopiImage avec l'option copieSrcEt on obtient bien une transparence sur l'ensemble de l'image sans dégradation sur les zones transparentes à l'origine. Par contre on ne peut pas régler le degrés de transparence.

    J'ai essayé dCopiImage avec l'option copieSrcEt suivi de CopieSrcPeint ça ne va pas.
    J'ai essayé dCopiImage avec l'option CopieSrcPeint seule ça ne va pas non plus.

    La procédure que j’expose permet de copier une image tout en voyant en transparence l'image en dessous (par exemple un photographe qui veut apposer son logo sur ses photos). On peut régler le degrés de transparence comme on le souhaite.

    C'est vrai que le traitement par pixel est plus long, mais ça reste raisonnable quand l'image n'est pas trop grande. Pour une image de 160x80 c'est à peut près une seconde. Il a l'avantage d'être plus propre puisqu'on peut gérer finement le degrés d'opacité. En l’occurrence pour mon photographe c'était très important.

    Par contre si on doit copier une image de grande taille et/ou copier sur un grand volume d'image il est avantageux d'utiliser dCopiImage avec l'option copieSrcEt si une qualité un peu moindre n'est pas gênante.

    Un grand merci à Hibernatus34 pour ces remarques
    Bon dev
    Laurent

    - C’est génial.
    - Non c’est bizarre.
    - Justement quand c’est simple y’a des milliers de réponses et quand c’est bizarre y’en a aucune.

  4. #4
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Pour la technique du SrcEt/SrcPeint, voici une vieille fonction qui fonctionnait (écrite avec une charte bizarre d'un client, désolé).
    On générait le masque une fois et ça permettait de dessiner rapidement ensuite.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    // dCopieImage avec transparence par masque
    PROCEDURE PG_dImageTransp(P_Dest, P_Src, P_Masque, LOCAL P_eX est entier = 0, LOCAL P_eY est entier = 0, LOCAL P_eLargeur est entier = -1, LOCAL P_eHauteur est entier = -1, LOCAL P_eXSrc est entier = 0, LOCAL P_eYSrc est entier = 0, LOCAL P_eLargeurSrc est entier = -1, LOCAL P_eHauteurSrc est entier = -1)
    SI P_eLargeur..Défaut OU P_eHauteur..Défaut ALORS
    	P_eLargeur = P_Src..Largeur
    	P_eHauteur = P_Src..Hauteur
    FIN
    SI P_eLargeurSrc..Défaut OU P_eHauteurSrc..Défaut ALORS
    	P_eLargeurSrc = P_Src..Largeur
    	P_eHauteurSrc = P_Src..Hauteur
    FIN
    dCopieImage(P_Masque, P_Dest, copieSrcEt, P_eXSrc, P_eYSrc, P_eHauteurSrc, P_eLargeurSrc, P_eX, P_eY, P_eHauteur, P_eLargeur)
    P_Src..CouleurFond = Noir
    dCopieImage(P_Src, P_Dest, copieSrcPeint, P_eXSrc, P_eYSrc, P_eHauteurSrc, P_eLargeurSrc, P_eX, P_eY, P_eHauteur, P_eLargeur)
    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
    // Crée un masque de transparence à partir d'une image avec du Magenta
    PROCEDURE PG_CréeMasqueImage(P_ChampImage, P_ChampMasque, P_bMàJImage = Faux)
    P_ChampMasque = dSauveImageBMP(P_ChampImage, enMémoire)
    dDébutDessin(P_ChampMasque)
    POUR y = 0 _A_ P_ChampMasque..Hauteur - 1
    	POUR x = 0 _A_ P_ChampMasque..Largeur - 1
    		SI dPixelCouleur(P_ChampMasque, x, y) = MagentaClair ALORS
    			dPoint(x, y, Blanc)
    		SINON
    			dPoint(x, y, Noir)
    		FIN
    	FIN
    FIN
    P_ChampMasque = dSauveImageBMP(P_ChampMasque, enMémoire)
    SI P_bMàJImage ALORS
    	dDébutDessin(P_ChampImage)
    	POUR y = 0 _A_ P_ChampImage..Hauteur - 1
    		POUR x = 0 _A_ P_ChampImage..Largeur - 1
    			SI dPixelCouleur(P_ChampImage, x, y) = MagentaClair ALORS
    				dPoint(x, y, Noir)
    			FIN
    		FIN
    	FIN
    	P_ChampImage = dSauveImageBMP(P_ChampImage, enMémoire)
    FIN
    Sinon, pour travailler l'opacité correctement, il faut travailler sur le type avancé Image, car un champ image perd sa transparence dès qu'il est utilisé dans une fonction de dessin. C'est pour ça que vous êtes obligé d'utiliser une color key.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    PROCEDURE Fusionne(imageSource, imageDest, x, y, opacité)
    imageTempSrc est Image	= imageSource
    imageTempDst est Image	= imageDest
    imageTemp est Image
    imageTemp.Largeur = imageTempSrc.Largeur
    imageTemp.Hauteur = imageTempSrc.Hauteur
    dCopieImage(imageTempDst, imageTemp, x, y, imageTemp.Hauteur, imageTemp.Largeur, 0, 0, imageTemp.Hauteur, imageTemp.Largeur)
    dFusionne(imageTemp, imageTempSrc, opacité)
    dCopieImage(imageTemp, imageTempDst, 0, 0, imageTemp.Hauteur, imageTemp.Largeur, x, y, imageTemp.Hauteur, imageTemp.Largeur)
    RENVOYER imageTempDst
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    dSauveImagePNG(Fusionne(IMG_Image1, IMG_Image2, 10, 10, 50), "Toto.png")
    PS. Je viens de comprendre ce que fait vraiment dFusionne : elle ne garde que la semi-transparence de l'image de fond. C'est sympa, mais ça aurait pu prendre en compte celle de l'image source aussi (pour la mise à jour de la couleur uniquement)... Ils sont pas doués chez PC Soft...

  5. #5
    Membre chevronné Avatar de laurent30s
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 881
    Points : 1 771
    Points
    1 771
    Par défaut
    Super ta PROCEDURE Fusionne(imageSource, imageDest, x, y, opacité)

    Elle fonctionne parfaitement et elle est ultra rapide, 9 centième de seconde !

    Merci pour la contribution
    Bon dev
    Laurent

    - C’est génial.
    - Non c’est bizarre.
    - Justement quand c’est simple y’a des milliers de réponses et quand c’est bizarre y’en a aucune.

  6. #6
    Membre expérimenté
    Inscrit en
    Août 2010
    Messages
    726
    Détails du profil
    Informations forums :
    Inscription : Août 2010
    Messages : 726
    Points : 1 645
    Points
    1 645
    Par défaut
    Oui, mais si l'image source contient de la semi-transparence, elle est perdue (ça devient opaque). Donc votre fonction fonctionne mieux dans ce cas.
    Personnellement j'ai abandonné le dessin dans WD depuis longtemps, je fais tout dans une DLL en C++. Et là je constate encore que j'ai bien fait, vu que PC Soft n'est même pas fichu de faire une fonction aussi simple que dFusionne correctement.
    Quand on voit qu'ils s'y sont repris à 3 fois pour faire une simple fonction de rotation...

  7. #7
    Membre chevronné Avatar de laurent30s
    Homme Profil pro
    Inscrit en
    Novembre 2007
    Messages
    881
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 881
    Points : 1 771
    Points
    1 771
    Par défaut
    Dommage qu'ils n'ont pas prévue que dCopieImage() gère l'opacité (et la gère correctement)
    Ça aurait été parfait...
    Bon dev
    Laurent

    - C’est génial.
    - Non c’est bizarre.
    - Justement quand c’est simple y’a des milliers de réponses et quand c’est bizarre y’en a aucune.

  8. #8
    Nouveau membre du Club
    Homme Profil pro
    IN
    Inscrit en
    Avril 2015
    Messages
    62
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Allemagne

    Informations professionnelles :
    Activité : IN

    Informations forums :
    Inscription : Avril 2015
    Messages : 62
    Points : 38
    Points
    38
    Par défaut
    salut à tous

    je suis interessé par la discutions je suis debuton en windev Je chercher comment copier une image source à l’endroit souhaité sur une image destination afin de sauvegarder l'image distination avec ''dsauvimage'' pour l'affecter au fichier de donnée avec "hattachmemo"

    (image distination est plus grand que l'image source je veux copie l'image source dans une partie précis sur l'image de distination)

    Merci davance

Discussions similaires

  1. Fusionner 2 images en gérant l'opacité
    Par laurent30s dans le forum WinDev
    Réponses: 2
    Dernier message: 11/02/2013, 10h59
  2. [VBA-E] fusionner 2 images sous excel
    Par richou dans le forum Macros et VBA Excel
    Réponses: 4
    Dernier message: 20/02/2007, 04h54
  3. Fusionner deux images, en fonction d'une condition
    Par Him dans le forum Balisage (X)HTML et validation W3C
    Réponses: 2
    Dernier message: 27/01/2007, 13h07
  4. [GD] Fusionner deux images GD
    Par ~~PriVate JoKe~~ dans le forum Bibliothèques et frameworks
    Réponses: 9
    Dernier message: 11/12/2006, 17h04
  5. [ImageMagick] Fusionner deux images
    Par eagleleader dans le forum Bibliothèques et frameworks
    Réponses: 10
    Dernier message: 26/05/2006, 17h30

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