[TUTO] Mélanger 2 images suivant un masque en noir et blanc

Informations pour bien débuter en PureBasic
G-Rom
Messages : 3641
Inscription : dim. 10/janv./2010 5:29

[TUTO] Mélanger 2 images suivant un masque en noir et blanc

Message par G-Rom »

L'idée est la suivante :

Image
On part avec trois images de base , de la terre , de l'herbe , et un masque en noir est blanc.
Le calcul du mélange est très simple :
couleur = (couleur_a * masque) + (couleur_b * (1-masque))
nous allons voir comment mettre en place facilement cette "formule".


- Dans un premier , nous devons charger nos images grâce aux commandes fournies de PureBasic

Code : Tout sélectionner

Image_A = LoadImage(#PB_Any,"Dirt.jpg")    ; La terre
Image_B = LoadImage(#PB_Any,"Grass.jpg")   ; L'herbe
Mask    = LoadImage(#PB_Any,"masque.png")  ; le masque
en admettant que la taille de l'image A n'est pas la même que l'image B , nous allons tout mettre à l'échelle du masque , comme ça pas de problème
de taille.

Code : Tout sélectionner

Reference_SizeX = ImageWidth(Mask)
Reference_SizeY = ImageHeight(Mask)

ResizeImage(Image_A,Reference_SizeX,Reference_SizeY)
ResizeImage(Image_B,Reference_SizeX,Reference_SizeY)
Pour nous faciliter les calculs , nous allons mettre dans des tableaux à deux dimensions la couleur des images.

Code : Tout sélectionner

Dim Image_A_Color(Reference_SizeX,Reference_SizeY)
Dim Image_B_Color(Reference_SizeX,Reference_SizeY)
Dim Image_C_Color(Reference_SizeX,Reference_SizeY)
De cette manière , on pourra faire nos calculs tranquillement avec les tableaux , et non directement les images.
on doit maintenant remplir nos tableaux avec les couleurs respectives de chaques images.

Code : Tout sélectionner

StartDrawing(ImageOutput(Image_A))
  For y = 0 To Reference_SizeY - 1
    For x = 0 To Reference_SizeX - 1
      Image_A_Color(x,y) = Point(x,y)
    Next
  Next 
StopDrawing() 
notez le -1 aux lignes : "For y = 0 To Reference_SizeY - 1" , si vous ne le faites pas , y a des chances pour que votre programme plante à cause d'un dépassement de mémoire , n'oubliez pas que 0 compte pour 1 !
faites de même pour l'image B
pour le masque , c'est un peut différent , on se fiche de connaitre la couleur RGB , ce qui nous intéresse c'est la valeur du niveau de gris , de 0 ( noir ) à 255 ( blanc )
aucune fonctions ne renvois cela , mais une petite opération de base nous permet de connaitre cette valeur :
niveau de gris = ( Composante rouge + Composante verte + composante bleue ) / 3
avec ce petit calcul , vous pouvez rendre n'importe quelle image en niveau de gris.

Code : Tout sélectionner

StartDrawing(ImageOutput(Mask))
  For y = 0 To Reference_SizeY - 1
    For x = 0 To Reference_SizeX - 1
      Color = Point(x,y)
      Image_C_Color(x,y) = (Red(Color) + Green(Color) + Blue(Color) ) / 3
    Next
  Next 
StopDrawing() 
Image_C_Color() contient donc une valeur entre 0 et 255.
ps : si vous vous amusez à créer une image à partir de ce tableau , votre image sera un dégradé de noir vers le rouge.

Nous avons tout ce qui faut pour mélanger nos couleurs , nous devons créer une image vide qui nous servira de "sortie" :

Code : Tout sélectionner

Sortie          = CreateImage(#PB_Any,Reference_SizeX,Reference_SizeY)
ensuite nous allons parcourir nos tableaux et extraire les composantes des couleurs pour nos opérations :

Code : Tout sélectionner

StartDrawing(ImageOutput(Sortie))
  For y = 0 To Reference_SizeY - 1
    For x = 0 To Reference_SizeX - 1
      
      
      Red_A     = Red(Image_A_Color(x,y))
      Green_A   = Green(Image_A_Color(x,y))
      Blue_A    = Blue(Image_A_Color(x,y))
      
      Red_B     = Red(Image_B_Color(x,y))
      Green_B   = Green(Image_B_Color(x,y))
      Blue_B    = Blue(Image_B_Color(x,y))
pour simplifié nos calculs , nous allons convertir la valeur du masque qui va de 0 à 255 à une valeur qui va de 0 à 1.

Code : Tout sélectionner

Value.f   = Image_C_Color(x,y) / 255
en admettant que Red_A = 255 et que value = 0.5 ( la moitié de 1 ) :

Code : Tout sélectionner

Resultat.f  =  Red_A * Value
resultat sera égal à 127.5 , la moitié aussi de 255 , simple calcul , non ?
reprenons notre formule vue toute en haut du topic :
couleur = (couleur_a * masque) + (couleur_b * (1-masque))
elle se traduit ainsi :

Code : Tout sélectionner

      Value.f   = Image_C_Color(x,y) / 255
      
      Red       =  (Red_A   * Value) + (Red_B   * (1-Value))
      Green     =  (Green_A * Value) + (Green_B * (1-Value))
      Blue      =  (Blue_A  * Value) + (Blue_B  * (1-Value))
      
      Plot(x,y,RGB(Red,Green,Blue))

    Next
  Next 
  StopDrawing()
et pour finir un petit :

Code : Tout sélectionner

SaveImage(Sortie,"Sortie.bmp")
Voilà , vous savez mélanger 2 images à partir d'un masque ! :wink:


Code complet (sans médias):

Code : Tout sélectionner

UseJPEGImageDecoder()
UseJPEGImageEncoder()

UsePNGImageDecoder()


Image_A = LoadImage(#PB_Any,"Dirt.jpg")
Image_B = LoadImage(#PB_Any,"Grass.jpg")
Mask    = LoadImage(#PB_Any,"masque.png")


Reference_SizeX = ImageWidth(Mask)
Reference_SizeY = ImageHeight(Mask)

ResizeImage(Image_A,Reference_SizeX,Reference_SizeY)
ResizeImage(Image_B,Reference_SizeX,Reference_SizeY)



Dim Image_A_Color(Reference_SizeX,Reference_SizeY)
Dim Image_B_Color(Reference_SizeX,Reference_SizeY)
Dim Image_C_Color(Reference_SizeX,Reference_SizeY)


StartDrawing(ImageOutput(Image_A))
  For y = 0 To Reference_SizeY - 1
    For x = 0 To Reference_SizeX - 1
      Image_A_Color(x,y) = Point(x,y)
    Next
  Next 
StopDrawing()
  
StartDrawing(ImageOutput(Image_B))
  For y = 0 To Reference_SizeY - 1
    For x = 0 To Reference_SizeX - 1
      Image_B_Color(x,y) = Point(x,y)
    Next
  Next 
StopDrawing()
  
StartDrawing(ImageOutput(Mask))
  For y = 0 To Reference_SizeY - 1
    For x = 0 To Reference_SizeX - 1
      Color = Point(x,y)
      Image_C_Color(x,y) = (Red(Color) + Green(Color) + Blue(Color) ) / 3
    Next
  Next 
StopDrawing()  

Sortie          = CreateImage(#PB_Any,Reference_SizeX,Reference_SizeY)


StartDrawing(ImageOutput(Sortie))
  For y = 0 To Reference_SizeY - 1
    For x = 0 To Reference_SizeX - 1
      
      
      Red_A     = Red(Image_A_Color(x,y))
      Green_A   = Green(Image_A_Color(x,y))
      Blue_A    = Blue(Image_A_Color(x,y))
      
      Red_B     = Red(Image_B_Color(x,y))
      Green_B   = Green(Image_B_Color(x,y))
      Blue_B    = Blue(Image_B_Color(x,y))

      Value.f   = Image_C_Color(x,y) / 255
      
      Red       =  (Red_A   * Value) + (Red_B   * (1-Value))
      Green     =  (Green_A * Value) + (Green_B * (1-Value))
      Blue      =  (Blue_A  * Value) + (Blue_B  * (1-Value))
      
      Plot(x,y,RGB(Red,Green,Blue))

    Next
  Next 
  StopDrawing()
  
  
  SaveImage(Sortie,"Sortie.bmp")
lepiaf31
Messages : 510
Inscription : dim. 25/mars/2007 13:44
Localisation : Toulouse, France
Contact :

Re: [TUTO] Mélanger 2 images suivant un masque en noir et bl

Message par lepiaf31 »

yeah ca pourrait m'être utile prochainement, merci =)
Backup
Messages : 14526
Inscription : lun. 26/avr./2004 0:40

Re: [TUTO] Mélanger 2 images suivant un masque en noir et bl

Message par Backup »

Tuto numero 46 ;)
Avatar de l’utilisateur
Ar-S
Messages : 9539
Inscription : dim. 09/oct./2005 16:51
Contact :

Re: [TUTO] Mélanger 2 images suivant un masque en noir et bl

Message par Ar-S »

Merci G-Rom, clair et précis (et joli rendu en plus) :)
~~~~Règles du forum ~~~~
⋅.˳˳.⋅ॱ˙˙ॱ⋅.˳Ar-S ˳.⋅ॱ˙˙ॱ⋅.˳˳.⋅
W11x64 PB 6.x
Section HORS SUJET : ICI
LDV MULTIMEDIA : Dépannage informatique & mes Logiciels PB
UPLOAD D'IMAGES : Uploader des images de vos logiciels
Avatar de l’utilisateur
SPH
Messages : 4937
Inscription : mer. 09/nov./2005 9:53

Re: [TUTO] Mélanger 2 images suivant un masque en noir et bl

Message par SPH »

Les 4 premieres images parlent d'elles memes. Ca rend tout de suite tres bien !

!i!i!i!i!i!i!i!i!i!
!i!i!i!i!i!i!
!i!i!i!
//// Informations ////
Intel Core i7 4770 64 bits - GTX 650 Ti
Version de PB : 6.12LTS- 64 bits
Avatar de l’utilisateur
venom
Messages : 3128
Inscription : jeu. 29/juil./2004 16:33
Localisation : Klyntar
Contact :

Re: [TUTO] Mélanger 2 images suivant un masque en noir et bl

Message par venom »

Un si petit code pour un beau rendu.
Merci G-Rom pour ce tuto :wink:








@++
Windows 10 x64, PureBasic 5.73 x86 & x64
GPU : radeon HD6370M, CPU : p6200 2.13Ghz
Répondre