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

 C Discussion :

comment programmer un effet neon sur les contours d'une image?


Sujet :

C

  1. #1
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut comment programmer un effet neon sur les contours d'une image?
    Bonjour,
    connaitriez vous un algo permettant de programmer un effet néon sur les contours d'une image?

  2. #2
    Expert éminent sénior
    Avatar de Kannagi
    Homme Profil pro
    cyber-paléontologue
    Inscrit en
    Mai 2010
    Messages
    3 214
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : France, Bouches du Rhône (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cyber-paléontologue

    Informations forums :
    Inscription : Mai 2010
    Messages : 3 214
    Points : 10 140
    Points
    10 140
    Par défaut
    Vu la question , j'ai envie de dire que cela n'a rien n'a voir avec le C :p
    (Je pense que il existe d'autre sous forum plus spécialisé dans ce domaine )

    Sinon un exemple d'effet de neon que tu veux ?
    Comme ceci par exemple ? http://www.mediatheque-beziers-agglo...=1&itemId=6141

    Le truc c'est que il faut déterminer les sources de lumière.
    Parce que ça me semble juste d’être un éclairage par pixel basic sinon.

  3. #3
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut
    Bonjour Kannagi.
    C'est bien l'effet que je recherche.

    Le truc c'est que il faut déterminer les sources de lumière.
    Parce que ça me semble juste d’être un éclairage par pixel basic sinon.
    Déteminer les sources de lumière, je ne sais pas faire, quant à éclairer les pixel, je sais faire, mais la question est : de quelle façon pour obtenir l'effet néon.

    Voici par exemple une fonction qui permet d'appliquer certains effets sur une image. Celà marche trés bien pour le flou de bougé, la mise en relief, et le flou tout court par exemple.

    Est il possible d'utiliser cette fonction pour l'effet néon? si oui, comment peut ont faire ça?

    Code c : 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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
     
     
      int* identity[3*3] = {
       0,  0,  0,
       0,  1,  0,
       0,  0,  0
     
    };
     
     
     
      int* relief[3*3] = {
      -1, -1, -1,
      -1,  9, -1,
      -1, -1, -1
     
    }; 
     
     
     
      int* flou_de_bouge[9*9] = {
       1,  0,  0, 0, 0, 0, 0, 0, 0,
       0,  1,  0, 0, 0, 0, 0, 0, 0,
     
       0,  0,  1, 0, 0, 0, 0, 0, 0,
       0,  0,  0, 1, 0, 0, 0, 0, 0,
       0,  0,  0, 0, 1, 0, 0, 0, 0,
       0,  0,  0, 0, 0, 1, 0, 0, 0,
       0,  0,  0, 0, 0, 0, 1, 0, 0,
       0,  0,  0, 0, 0, 0, 0, 1, 0,
       0,  0,  0, 0, 0, 0, 0, 0, 1      
    };  
     
     
      int* gaussian_blur[3*3] = {
      1, 2, 1,
      2, 4, 2,
      1, 2, 1
    };
     
    image image_filter_TGA24 (image I, int* K, int kCols, int kRows, float divisor)
    {
     /*kCols = nb de colonnes du kernel, kRows = nb de lignes du kernel*/
     int kCenterX = kCols / 2;
     int kCenterY = kRows / 2;
     int i, j, m, mm, n, nn, ii, jj;
     
    image J = image_create (I->w, I->h, 0xFF0000FF);
    image_save_TGA24 ("./IMAGES/imageTGA24_filter.tga", J);
    jfile F = standard_jfile_open ("./IMAGES/imageTGA24_filter.tga", JFILE_MODE_READ);
     
     for (i = 0; i < 16; i++)
      jfile_read_char(F);
     
     for(j=0; j < I->h ; j++)            
     {
     
        for(i=0; i < I->w; i++)         
        {
         byte r=0;
         byte g=0;
         byte b=0;
     
            for(m=0; m < kCols; m++)    
            {
                mm = kCols - 1 - m;      
     
                for(n=0; n < kRows; n++) 
                {
                    nn = kRows - 1 - n;
     
     
                    ii = i + (n - kCenterX);
                    jj = j + (m - kCenterY);
     
     
                    if( ii >= 0 || ii < I->w || jj >= 0 || jj < I->h )
                     {
                       byte rr, gg, bb;
     
                       colour_get_rgb ((colour)(long) I->pixel + jj * I->w + ii, &rr, &gg, &bb); 
     
                       if (r < 0) r = 0; if (r > 255) r = 255;
                       if (g < 0) g = 0; if (g > 255) g = 255;
                       if (b < 0) b = 0; if (b > 255) b = 255;                   
     
                       r += /*I->pixel [jj * I->w + ii] * (K[nn * kRows + mm]);*/(rr * (K[nn * kRows + mm] )) / divisor;
                       g += /*I->pixel [jj * I->w + ii] * (K[nn * kRows + mm]);*/(gg * (K[nn * kRows + mm] )) / divisor;
                       b += /*I->pixel [jj* I->w + ii] * (K[nn * kRows + mm]);*/(bb * (K[nn * kRows + mm] )) / divisor;
                       J->pixel[j * I->w + i] = make_colour(r, g, b, 0xFF);
     
                     }   
                }
            }
        }
     }
     
     image_save_TGA24 ("./IMAGES/image_filter_TGA24.tga", J);
     jfile_close(&F);
     return J;
    }

  4. #4
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Points : 649
    Points
    649
    Par défaut Effet basique et techniques
    Flou gaussien + Affichage par transparence. Après ça dépend du résultat recherché car en infographie il existe plusieurs techniques.

  5. #5
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut
    ok, l'effet que je recherche est celui qui correspond au lien posté par Kannagi dans la présente discussion.

    Par exemple, calculer un effet néon sur le rectangle jaune.
    je vais essayer le flou gaussien + transparence.
    Images attachées Images attachées  

  6. #6
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Points : 649
    Points
    649
    Par défaut Formes "creuses" et pistes
    Plutôt que des formes pleines je te conseille des lignes afin de reproduire la structure d'une lampe néon. Sinon une astuce pour t'aider c'est de tester l'effet avec un éditeur d'images. Les fonctionnalités existent déjà et à partir de là tu peux déterminer le processus. Faire quelques didacticiels d'infographie au besoin ça peut aussi être une piste.

  7. #7
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut
    Bonjour,
    je reviens à vous car après des semaines de retournement de cerveau, j'ai à peu près réussi à faire ce que je voulais.
    voici comment je procède :

    A a place de dessiner un pixel, je dessine un disque avec les algos de Bresenham. Ensuite je pars du centre jusqu'à la périphérie, et pour chaque ligne remplissant le cercle, je calcule une transparence de plus en plus forte.
    Pour la seconde image, ce n'est pas un cercle qui forme le pixel "neon" mais un calcul qui ajoute des x ou des y au point du pixel.
    Ca vaut ce que ca vaut, mais c'est de moi.
    Je ne sais pas du tout si au niveau temps d'éxécution, c'est bien ou non.
    Voici plusieurs images avec plusieurs façons de programmer un effet néon.

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    void image_putpixel_neon (image I, int x, int y, colour c, int epaisseur)
    {
     byte r, g, b, a;
     colour_get_rgba (c, &r, &g, &b, &a); 
     bresenham_disk_modifie_transparence (I, epaisseur, x, y, r, g, b, 50);
    }




    Code c : 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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    void bresenham_disk_modifie_transparence (image I, int rayon, int x_centre, int y_centre, byte r, byte g, byte b, byte a)
    {
     int x, y, m;
     x = 0;
     
     y = rayon;
     
     m = 5 - (4 * rayon);
     
     while (x <= y)
      {
       colour* ptr = NULL;
     
       /*octants de 1 à 8, dans le sens des aiguilles d'une montre*/
     
       ptr = I->pixel + /*octant1*/(-y + y_centre) * I->w + (x + x_centre);
         if ((x + x_centre) >= 0 && (x + x_centre < I->w) && (-y + y_centre) >= 0 && (-y + y_centre) < I->h)
          {
           /*image_putpixel_alpha (ptr, r, g, b, 127);*/
           bresenham_modifie_transparence (I, x_centre, y_centre, x + x_centre, -y + y_centre, r, g, b, rayon);
     
          }
     
       ptr = I->pixel + /*octant2*/(-x + y_centre) * I->w + (y + x_centre);
         if ((y + x_centre) >= 0 && (y + x_centre < I->w) && (-y + y_centre) >= 0 && (-y + y_centre) < I->h)
          /*image_putpixel_alpha (ptr, r, g, b, a);*/
          bresenham_modifie_transparence (I, x_centre, y_centre, y + x_centre, -x + y_centre, r, g, b, rayon);
     
     
    /*OCTANT 3 NE FONCTIONNE PAS*/
       ptr = I->pixel + /*octant3*/(x + y_centre) * I->w + (y + x_centre);
         /*if ((y + x_centre) >= 0 && (y + x_centre < I->w) && (x + y_centre) >= 0 && (x + y_centre) < I->h)   */
           /*image_putpixel_alpha (ptr, r, g, b, a);*/
            bresenham_modifie_transparence (I, x_centre, y_centre, y + x_centre, x + y_centre, r, g, b, rayon);
     
     
     
     
     
     
       ptr = I->pixel +/* octant4*/(y + y_centre) * I->w + (x + x_centre) ;
         if ((x + x_centre) >= 0 && (x + x_centre < I->w) && (y + y_centre) >= 0 && (y + y_centre) < I->h)   
          /*image_putpixel_alpha (ptr, r, g, b, a);*/
          bresenham_modifie_transparence (I, x_centre, y_centre, x + x_centre, y + y_centre, r, g, b, rayon);
     
     
     
     
       ptr = I->pixel + /*octant5*/(y + y_centre) * I->w + (-x + x_centre) ;
         if ((-x + x_centre) >= 0 && (-x + x_centre < I->w) && (y + y_centre) >= 0 && (y + y_centre) < I->h)   
          /*image_putpixel_alpha (ptr, r, g, b, a);*/
           bresenham_modifie_transparence (I, x_centre, y_centre, -x + x_centre, y + y_centre, r, g, b, rayon);
     
     
     
       ptr = I->pixel + /*octant6*/(x + y_centre) * I->w + (-y + x_centre);
         if ((-y + x_centre) >= 0 && (-y + x_centre < I->w) && (x + y_centre) >= 0 && (x + y_centre) < I->h)   
          /*image_putpixel_alpha (ptr, r, g, b, a);*/
           bresenham_modifie_transparence (I, x_centre, y_centre, -y + x_centre, x + y_centre, r, g, b, rayon);
     
       ptr = I->pixel + /*octant7*/(-x + y_centre) * I->w + (-y + x_centre);
         if ((-y + x_centre) >= 0 && (-y + x_centre < I->w) && (-x + y_centre) >= 0 && (-x + y_centre) < I->h)   
          /*image_putpixel_alpha (ptr, r, g, b, a);*/
           bresenham_modifie_transparence (I, x_centre, y_centre, -y + x_centre, -x + y_centre, r, g, b, rayon);     
     
     
     
       ptr = I->pixel + /*octant8*/(-y + y_centre) * I->w + (-x + x_centre);
         if ((-x + x_centre) >= 0 && (-x + x_centre < I->w) && (-y + y_centre) >= 0 && (-y + y_centre) < I->h)   
          /*image_putpixel_alpha (ptr, r, g, b, a);*/
           bresenham_modifie_transparence (I, x_centre, y_centre, -x + x_centre, -y + y_centre, r, g, b, rayon);   
     
       if (m > 0)
        {
         y--;
         m = m - 8 * y;
        }
     
       x++;[ATTACH=CONFIG]271190[/ATTACH]
       m = m + (8 * x) + 4; 
      }
    }

    (le troisième octant ne fonctionne pas)


    voici les images :

    Au passage, message pour Jacques Olivier Lapeyre : dans tes lectures de commentaires de ta chaine youtube, tu parles du pseudo Moi Moi en disant qu'il est fou (dans le bon sens du terme) d'avoir regardé tes vidéos en entier. Merci pour le compliment, il s'agit de moi. Merci encore pour tes videos.

    Nom : A.png
Affichages : 815
Taille : 46,8 Ko

    Nom : A1.png
Affichages : 786
Taille : 74,3 KoNom : A2.png
Affichages : 898
Taille : 45,3 Ko

  8. #8
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut
    voici également le code pour choisir la couleur qu'on veut "néoner" dans une image:
    (le code commenté a été utilisé pour l'image jaune ci dessus)
    Code c : 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
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    void choose_colour_to_glow (image I, colour d)
    {
     int x, y, i;
     colour c;
      for ( y = 0; y < I->h; y++)
      {
       for (x = 0; x < I->w; x++)
        {
         c = I->pixel[y * I->w + x];
     
         if (c == d) 
          {
     
           byte rr, gg, bb, aa;
     
           colour_get_rgba (d, &rr, &gg, &bb, &aa);
           image_putpixel_neon (I, x, y, d, 10);     
     
    /*
           for (i = 0; i < 15; i++)
            {
             if (x + i >= 0 && x + i < I->w && y + i >=0 && y + i < I->h && x - i >=0 && x - i < I->w
                && y - i >= 0 && y - i < I->h)
             {
              
             
              image_putpixel_alpha (I->pixel + (y + i) * I->w + x, rr, gg, bb, aa - (i * 17));
              image_putpixel_alpha (I->pixel + (y - i) * I->w + x, rr, gg, bb, aa - (i * 17));
              image_putpixel_alpha (I->pixel + y * I->w + (x + i), rr, gg, bb, aa - (i * 17));
              image_putpixel_alpha (I->pixel + y * I->w + (x - i), rr, gg, bb, aa - (i * 17));
             
              image_putpixel_alpha (I->pixel + (y + i) * I->w + (x-i), rr, gg, bb, aa - (i * 17));
              image_putpixel_alpha (I->pixel + (y - i) * I->w + (x-i), rr, gg, bb, aa - (i * 17));
              image_putpixel_alpha (I->pixel + (y+i) * I->w + (x + i), rr, gg, bb, aa - (i * 17));
              image_putpixel_alpha (I->pixel + (y-i) * I->w + (x + i), rr, gg, bb, aa - (i * 17));
              
             }
           
           
             
            } 
    */
     
     
          }
     
     
        }
     
      }
     
    }

    qui donne par exemple:

    (on peut choisir d'allumer seulement le blanc, le vert ou bien le rouge)

    Nom : A4.png
Affichages : 819
Taille : 63,9 Ko

  9. #9
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Points : 649
    Points
    649
    Par défaut Expérimentation, traitement d'image et amélioration
    C'est astucieux d'utiliser cet algorithme et je t'encourage à expérimenter surtout compte tenu du résultat encourageant. Par contre je comprends pas pourquoi tu t'es éloigné des solutions de départ surtout qu'en remontant je suis tombé sur le code correspondant exactement à celle que je t'avais proposé. Ici la tienne se rapproche plus d'un effet de brosse : Circulaire, étoilée… À défaut d'être du traitement d'image pur ça pourrait donc servir pour dessiner. D'ailleurs ta 1ère image me laisse à penser que tu as un petit outil pour tracer des courbes.

    Sinon quelles sont tes pistes d'amélioration ? Je pense niveau performance, car l'algo est un gouffre pour cet usage, et rendu visuel. J'ai notamment remarqué les inévitables trous. Sinon même si tu t'es amusé, tout en t'arrachant un peu les cheveux parfois à mon avis, il ne faut pas négliger l'apprentissage et je pense notamment aux concepts mathématiques derrière. Mais réinventer la roue et partir dans d'autres directions en fonction de ses connaissances c'est aussi enrichissant. Faut trouver le juste équilibre !

    Donc bravo et la prochaine fois faut poster un néon rigolo car sur la 3e image le pauvre bonhomme tire un peu la gueule héhé. Pas content de ses néons colorés le Léon ?!

  10. #10
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut
    Salut,
    merci pour tes encouragements, ohnomorejmmings, vu comment j'ai transpiré pour arriver à ce petit résultat, ça fait plaisir de voir que quelqu'un l'aprécie.
    Pour ce qui est des améliorations algorithmiques, je n'ai pas encore réfléchi à la question. J'y penserai quand j'aurais un truc qui me plait pleinement (quand il n'y aura plus de trous par exemple, ou bien que le 3eme octant de mes cercles fonctionnera).

    Ma première image a été faite à la main, en tatonnant comme un malade pour les x et les y. J'envisage de faire justement un petit utilitaire pour faire cela graphiquement, mais je n'ai pas bien compris comment implémenter un drag and drop. J'ai déjà posté la question sur ce forum, et j'ai compris la réponse, par contre pour le faire tourner graphiquement, c'est autre chose. Je voudrais me servir de pointeurs de fonction. Par exemple tirer sur l'extrémité d'un segment de droite donne une autre orientation à la courbe.
    Dans ma fonction qui trace des courbes de Bézier, j'utilise un booléen qui permet d'afficher ou non les traits droits qui donnent l'orientation à la courbe.

    J'aimerais aussi changer la position de la couleur la plus blanche du néon en fonction d'une autre source lumineuse que je placerai dans l'image.
    Donc, si je réussis, je reviens ici pour montrer un smiley, content cette fois ci, de s'être fait néoner!

  11. #11
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut
    Citation Envoyé par ohnomorejmmings Voir le message
    Sinon quelles sont tes pistes d'amélioration ?
    Je reviens ici car j'ai trouvé un autre algorithme sur wikipedia, il s'agit des cercles d'andres :
    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
     
    x <- 0
    y <- r
    d <- r - 1
    Tant que y>=x 
            tracerPixel( x_centre + x , y_centre + y )
            tracerPixel( x_centre + y , y_centre + x )
            tracerPixel( x_centre - x , y_centre + y )
            tracerPixel( x_centre - y , y_centre + x )
            tracerPixel( x_centre + x , y_centre - y )
            tracerPixel( x_centre + y , y_centre - x )
            tracerPixel( x_centre - x , y_centre - y )
            tracerPixel( x_centre - y , y_centre - x )
            Si d >= 2x alors 
                    d <- d-2x-1
                    x <- x+1
            Sinon Si d < 2(r-y) alors
                    d <- d+2y-1
                    y <- y-1     
            Sinon 
                    d <- d+2(y-x-1)
                    y <- y-1
                    x <- x+1
    Fin de tant que

    j'ai traduit cet algorithme en langage c et cela donne un résultat qui se rapproche au plus près de ce que je veux.
    voici une image programmée par moi, où chaque disque a pour rayon 255, ce qui permet de passer par les 255 valeurs de transparence.
    La fonction que j'ai écrite permet de recalculer une transparence acceptable quel que soit le diamètre du disque qu'on choisit.

    Cela me plait vraiment pour UN disque, en revanche, lorsque je veux réduire la taille pour "allumer" une forme, c'est la cata.
    Par exemple, une ligne rouge que je veux "néoner" devient floue et il manque l'éclat blanc au milieu.
    Encore de quoi bien me retourner le cerveau en perspective.
    Images attachées Images attachées  

  12. #12
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Est-ce qu'il ne faut pas tout simplement attribuer à chaque pixel une valeur d'« intensité lumineuse » proportionnelle à sa distance (ou au carré de sa distance) à l'élément qui génère le halo (point, droite, courbe, silhouette d'une forme convexe..) ?

  13. #13
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut
    Bonjour Matt_Houston.

    Une intensité lumineuse à chaque pixel? Si je comprends bien, il faut que je convertisse mes pixels rgb en pixels hsl.

    j'ai réussi à traduire l'algo du site http://http://www.rapidtables.com/co...rgb-to-hsl.htm

    en langage c pour convertir une couleur rgb en couleur hsl, en passant par une structure H qui a pour champs r, g, b:

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    typedef struct _HSL *HSL;
     
    struct _HSV {
     float h;
     float s;
     float v;
     float l;
     
     byte r;
     byte g;
     byte b;
    };

    ce qui donne en fonction :

    Code c : 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
    void RGB_to_HSL (HSV H, byte r, byte g, byte b)
    {
     float r_prime = H->r /255.0;
     float g_prime = H->g /255.0;
     float b_prime = H->b /255.0;
     float Cmax = ffind_max (r_prime, g_prime, b_prime);
     float Cmin = ffind_min (r_prime, g_prime, b_prime); 
     float delta = Cmax - Cmin;
    /* 
     if (Cmax == r_prime) fprintf (stderr, "\nCmax = r_prime\n");
     else if (Cmax == g_prime) fprintf (stderr, "\nCmax = g_prime\n");
     else if (Cmax == b_prime) fprintf (stderr, "\nCmax = b_prime\n");  
     */
     
     H->l = (Cmax + Cmin) / 2.0;
     H->r = r;
     H->g = g;
     H->b = b;
     
     /*Hue calculation*/
     
     if (delta == 0.0)
      {
      H->h = 0.0;
      H->s = 0.0;
      }
     else if (delta != 0) 
      H->s = delta / (1.0 - fabs(2.0 * H->l - 1.0));
     
     
     if (Cmax == r_prime)
      H->h = 60.0 * fmod(((g_prime - b_prime) / delta) ,6.0);
     else if (Cmax == g_prime)
      H->h = 60.0 * ((b_prime - r_prime) / delta + 2.0) ;
     else if (Cmax == b_prime)
      H->h = 60.0 * ((r_prime - g_prime) / delta + 4.0 );
     /*
      fprintf (stderr, "\n\nH->h = %f, H->s = %f, H->l = %f\n\n", H->h, H->s, H->l);
    */
    }

    et voici une image qui joue sur hsl et non rgb :

    il faudrait que j'arrive à intervertir les couleurs blanches et noires.
    Images attachées Images attachées  

  14. #14
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    En réalité je n'entendais le terme qu'en tant que notion spécifique à ton problème d'effet néon, ce pourquoi je l'ai écrit entre guillemets. Je ne pensais pas du tout au codage de la couleur.

    Pour éviter la confusion, je vais reformuler et parler de « quantité d'énergie » reçue par chaque pixel : cette dernière est maximale sur les pixels qui composent l'objet auquel est appliqué l'effet puis décroit à mesure que l'on s'en éloigne. Ça se modélise de manière assez directe en passant sur chaque pixel et en lui attribuant l'énergie qu'il reçoit en fonction de sa distance à l'objet (calculée via une projection orthogonale s'il s'agit d'une ligne, par exemple).

    C'est une simple idée, je n'ai jamais programmé cet effet en software / séquentiel (par opposition à un bloom sur GPU).

  15. #15
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Points : 649
    Points
    649
    Par défaut Simulation d'éclairage
    Calculer la luminosité de chaque pixel rejoint l'approche pour le lancer de rayon ou un moteur d'éclairage. Trop compliqué à mon avis pour simuler un simple effet de néon surtout qu'il y aurait beaucoup trop de "pixels sources" à prendre en compte.

  16. #16
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Points : 649
    Points
    649
    Par défaut Nouvel algo et persévérance
    Ne sous-estimes pas les progrès faits avec ton dernier résultat. En plus d'avoir comblé les trous tu as de beaux halos colorés ! En combinant tout ça avec tes dessins tu devrais t'approcher encore plus de l'effet tant convoité. Allez hop on agrandit les centres hyper lumineux pour éclater le forum ! Ensuite on applique tout ça à des hordes de formes pixelisées !!

    PS : Attention t'as marqué cette discussion comme résolue

  17. #17
    Expert confirmé
    Inscrit en
    Mars 2005
    Messages
    1 431
    Détails du profil
    Informations forums :
    Inscription : Mars 2005
    Messages : 1 431
    Points : 4 182
    Points
    4 182
    Par défaut
    Je t'accorde que ça ne doit pas être le meilleur rapport qualité / performance. Cela dit il y a toujours manière de définir une AABB ou une OOBB de la zone à prendre en compte et l'opération est aisément parallélisable puisque les contributions à différents pixels peuvent être déterminées indépendamment (ou en grande partie).

    Mais bon là encore ce sont mes suppositions : je n'ai pas votre recul pratique.

  18. #18
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut
    re!
    c'est cool de voir que le sujet vous intérresse.

    j'ai donc encore bien galéré pour vous présenter ce qui suit:

    voici une image qui mélange plusieurs algos. J'ai repris l'idée initiale et j'ai suivi ton conseil ohnomorejmmings, c'est à dire que je n'ai pas laissé tombé les cercles d'andres.

    Pour une ligne horizontale, je calcule d'abord des cercles d'andres dont les x_centre et les y_centre sont placés aléatoirement de part et d'autre de la ligne (c'est à dire que le centre du cercle est un nombre aléatoire compris entre les x et les y de la ligne elle même et une certaine valeur qu'on peut modifier).

    Je répète l'opération avec des cercles de rayon légèrement plus petits.

    Pour chaque cercle, la transparence, elle, est fixe.

    Ensuite, je dessine une ligne "néon" blanche aux coordonnées de la ligne précédemment calculée.

    Voilà pour l'instant.

    En ce qui concerne la rapidité d'exécution, voici ce que cela donne pour l'image ci dessous (image tga 24 en 800x800):

    real 0m0.188s
    user 0m0.180s
    sys 0m0.004s

    question à Matt_Houston : qu'est ce qu'une AABB ou une OOBB?
    Images attachées Images attachées  

  19. #19
    Membre confirmé
    Profil pro
    Inscrit en
    Mai 2011
    Messages
    252
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2011
    Messages : 252
    Points : 649
    Points
    649
    Par défaut Quelques remarques
    Ça progresse, ça progresse. Super !

    Par contre je ne comprends pas trop l'utilisation du hasard même si ça donne un rendu unique. Aussi finalement ça fait plus laser maintenant non ? Ça reste trop propre pour comparer avec l'image postée par Kannagi. Le néon ça bave quoi comme quand le Léon a trop bu !

    Le centre blanc fonctionne plus ou moins bien selon les couleurs. Par exemple pour le bleu je verrai plus du cyan. Ça sera d'autant plus visible quand il sera plus étalé.

    Je critique et c'est bon signe car je sens que la prochaine fois ça sera encore mieux. En plus ta technique devrait aussi s'adapter à d'autres formes…

    PS : Hum pour que des stats soient crédibles faut donner les spécs du Tron générant ce monde électropsychédélique

  20. #20
    Membre actif

    Homme Profil pro
    autre
    Inscrit en
    Juillet 2015
    Messages
    176
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : autre

    Informations forums :
    Inscription : Juillet 2015
    Messages : 176
    Points : 202
    Points
    202
    Par défaut
    Hello.
    Alors, pour faire baver le néon (ou plutôt donner une vague impression de fumée diffuse dans mon cas), j'ai besoin du hasard justement. Voici le bout de code que j'ai modifié, écoutant à nouveau tes conseils:

    Code c : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    for (i = 0; i < rayon * my_rand(1, 100); i++) 
       image_cercle_d_andres (I, my_rand(x_centre-25, x_centre+25 ), my_rand(y_centre- my_rand(25,     255), y_centre + 
       my_rand(25, 255)), i, r, g, b, /*a-= x*/2);

    Je m'explique : pour chaque pixel sur la ligne horizontale, je calcule un rayon en 1 et 100.
    Je longe toute la ligne horizontale, et je place des cercles un peu partout, dont les x_centre sont compris entre x_centre - 25 et x_centre + 25 => c'est le sens horizontal de l'image,
    et dont les y_centre sont situés entre 25 et 255 => c'est le sens vertical.

    C'est ce qui me permet d'obtenir une sorte d'effet fuménoïde.
    Images attachées Images attachées  

Discussions similaires

  1. Réponses: 1
    Dernier message: 18/12/2016, 17h55
  2. Dessiner les contours d'une image
    Par kabylie dans le forum Images
    Réponses: 2
    Dernier message: 22/12/2011, 17h56
  3. Renforcer les contours dans une image
    Par Chatbour dans le forum Traitement d'images
    Réponses: 2
    Dernier message: 27/04/2009, 14h00
  4. Réponses: 4
    Dernier message: 11/09/2008, 15h21
  5. Comment faire un tail -f sur les logs binaires mysql-bin ?
    Par mediaforest dans le forum Requêtes
    Réponses: 8
    Dernier message: 24/09/2005, 12h34

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