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

Traitement d'images Discussion :

Uniformisation de couleurs dans un dégradé : comment faire ?


Sujet :

Traitement d'images

  1. #41
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    Tu maîtrises désormais les variantes de la fonction Coef_C.
    Le montage que je découvre à l'instant serait encore plus démonstratif si tu inversais l'ordre des 4 premières bandes. Je suis mesquin.
    Non ! Tu es taquin
    L'inversion, comme ça ? (30 secondes avec Gimp) :
    Nom : variantes_inv.jpg
Affichages : 197
Taille : 16,9 Ko
    Le bleu me fait penser à l'étambot d'un navire "de ligne" du XVIIIe siècle,

    Citation Envoyé par wiwaxia Voir le message
    Je reviendrai plus tard sur le tracé des courbes.
    Dacodac...

    Citation Envoyé par wiwaxia Voir le message
    PS: Il y a encore mieux pour modifier les étendues relatives des couleurs: remplacer (w) par la fonction homographique u = (g*w)/(1 + (g-1)*w) , en prenant:
    g = 2n, avec (n) entier situé dans [-5 ; +5].
    Les graphes sont pour (g) différent de (1) des portions d'hyperboles équilatères passant par les points (0, 0) et (1 , 1); l'observation du faisceau de courbes sur une calculatrice permet de comprendre ce qui se passe.
    Encore du boulot !

    EDIT :
    Citation Envoyé par wiwaxia Voir le message
    [...] remplacer (w) par la fonction homographique u = (g*w)/(1 + (g-1)*w) [...]
    Je ne vois pas , et je ne vois pas comment...

    J'ai bien sûr cherché "fonction homographique", me suis retrouvé sur une page Wikipédia où j'avoue humblement (mais je l'ai déjà dit au tout début de ce fil) n'avoir rien compris...
    C'est pas ma tasse de thé, c'est comm' ça...
    /EDIT
    ---

    De mon côté, j'ai optimisé le plus possible (viré tous les float, real et autres, remplacés par des integer et bytes : ben oui, au final un TColor est plein de bytes et c'est tout), ton code s'exécute en 55 millisecondes et le mien en... 26 !


    Et voilà comment :
    Code pascal : 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
    type
      TPixelsLine = array[0..1535] of TColor; // 1536 px, largeur du buffer de travail
      pPixelsLine = ^TPixelsLine;
    var
      PixelsLine: pPixelsLine;
      dst: TBitmap;
      function ColorBGR(LargeurMax, idx: integer): TColor;
      var
        aByte: byte;
        Section, NbreSections: integer;
        LargeurSection: integer;
      begin
        NbreSections := 6; // la valeur à changer (1 à 8)
        LargeurSection := LargeurMax div NbreSections;
        Section := idx * NbreSections div LargeurMax;
        Section := Section + 1; // pour comparer le timing avec wiwaxia -- utile si NbreSec = 6
        aByte := (idx * 255 div LargeurSection)-(255 * Section);// 1 à 8 dégradés ok
     
        case (Section) of     // -B- -G- -R- /!\ /!\ /!\
          0: Result := RGBtoColor(0, 0, aByte);       // noir à rouge : bien pour commencer
          1: Result := RGBtoColor(0, aByte, 255);     // rouge à jaune
          2: Result := RGBtoColor(0, 255, 255-aByte); // jaune à vert
          3: Result := RGBtoColor(aByte, 255, 0);     // vert à cyan
          4: Result := RGBtoColor(255, 255-aByte, 0); // cyan à bleu
          5: Result := RGBtoColor(255, 0, aByte);     // bleu à magenta
          //5: Result := RGBtoColor(255-aByte, 0, 0);     // bleu à noir
          6: Result := RGBtoColor(255-aByte, 0, 255); // magenta à rouge
          //6: Result := RGBtoColor(255-aByte, 0, 255-aByte); // magenta à noir
          //6: Result := RGBtoColor(255, aByte, 255); // magenta à blanc
          //6: Result := RGBtoColor(aByte, 0, aByte); // noir à magenta
          7: Result := RGBtoColor(255, aByte, 255);   // magenta à blanc pour jouer
          //7: Result := RGBtoColor(255-aByte, 255-aByte, 255-aByte);   // blanc à noir pour jouer
          else Result := clBlack;
        end;
      end;
      procedure ComputeGradientWithScanline(bmp: TBitmap);
      var
        r,g,b: byte;
        h,w: integer;
      begin
        with bmp do begin
          GetMem(PixelsLine, Width*SizeOf(TColor));
          BeginUpdate();
          for h := 0 to Height-1 do begin
            PixelsLine := pPixelsLine(RawImage.GetLineStart(h));
            for w := 0 to Width-1 do 
              PixelsLine^[w] := ColorBGR(Width, w); // 26 millisec (55 pour wiwaxia)
          end;
          EndUpdate();
        end;
      end;

    Et si on voit le bout du tunnel de tout ça, je te propose ensuite de réfléchir à la représentation des couleurs de la lumière visible (si c'est un peu ta partie) parce qu'en tapant juste "lumière visible" et en regardant les images remontées par google, on peut admirer tout et n'importe quoi...

  2. #42
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    Je reviendrai plus tard sur le tracé des courbes.
    Chose promise, chose dûe. Et comme les options s'accumulent, les programmes s'allongent et je vais être bientôt confronté à un décalage gênant.

    Les calculs sont faits sur une matrice occupant 12 millions d'octets, et susceptible de mémoriser 4 mégapixels (j'ai eu la main lourde). Elle est définie et initialisée dans une unité réservée que le Turbo Pascal serait évidemment incapable de compiler:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     CONST Dim_Max = 2000;
    
     TYPE Pixel = ARRAY[1..3] OF Byte;
          Tab_Pix = ARRAY[1..Dim_Max, 1..Dim_Max] OF Pixel;
    
     VAR Haut_Image, Larg_Image, Prod_LaHa: Z_32;          // Z_32 = LongInt
         Matr_Image: Tab_Pix;
    Cette variable devient incontournable dès qu'il s'agit de tracer des graphiques ou des nuages de points, à l'aide de Virtual Pascal.
    Le calcul des pixels (au départ tous noirs - 0, 0, 0) s"effectue en deux temps:
    a) le tracé des graphes dans la partie inférieure de l'image (procédure CalcMat_Im01));
    b) le badigeonnage de la partie supérieure, avec les teintes attendues (procédure CalcMat_Im02).

    Pour les courbes le nombre total de points (2*Lim + 1) doit être suffisamment élevé, afin de conduire à un tracé continu; l'apparition d'un pointillé n"est pas évitable dans le cas présent, lorsque la tangente devient verticale.

    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
     
     PROCEDURE CalcMat_Im02(La, Ha: Z_32; VAR Ma: Tab_Pix);
       CONST Lim = 5000; h = 2 / 3; m = 255;
       VAR K1, x, y: Z_32; r, s: Reel; Px: Pixel;
       BEGIN
         K1:= Round(0.55 * Ha); ;
         FOR x:= 1 TO La DO
           FOR y:= K1 TO Ha DO
             BEGIN
               s:= (x - 1)/(La - 1); r:= (2 * s) - 1;
               s:= Coef_C(Pilote, r + h);    Px[1]:= Round(m * s);
               s:= Coef_C(Pilote, r);        Px[2]:= Round(m * s);
               s:= Coef_C(Pilote, r - h);    Px[3]:= Round(m * s);
               Ma[x, y]:= Px
             END
       END;
     
     PROCEDURE CalcMat_Im01(La, Ha: Z_32; VAR Ma: Tab_Pix);
       CONST Lim = 5000; h = 2 / 3; m = 10;
             Cbl = 255; Cve = Cbl * 1000; Cro = Cve * 1000;
       VAR k, K1, x, y: Z_32; r, s: Reel;
       BEGIN
         K1:= Round(0.45 * Ha); Dec(K1);
         FOR k:= -Lim TO Lim DO
           BEGIN
             r:= k / Lim;       s:= (r + 1) * (La - 1);
             x:= Round(s / 2);  Inc(x);
             s:= Coef_C(Pilote, r);     y:= Round(K1 * s);
             Ma[x, y+m]:= Couleur_P(Cve);
             s:= Coef_C(Pilote, r + h); y:= Round(K1 * s);
             Ma[x, y+m]:= Couleur_P(Cro);
             s:= Coef_C(Pilote, r - h); y:= Round(K1 * s);
             Ma[x, y+m]:= Couleur_P(Cbl)
           END
       END;
    Avec les outils dont tu disposes, tu dois certainement trouver l'équivalent de la matrice en question (une variable TBitmap, peut-être ?).

    ... Encore du boulot ! ...
    Mais non, mais non, juste un petit bricolage installé en fin de codage de la fonction Coef_C(Pilote, t), avec un paramètre d'option (variable 'Pilote'):
    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
     
     
     VAR Pilote: Byte; g: Reel;
     
     FUNCTION CcG(G1, W1: Reel): Reel;
       VAR p, q: Reel;
       BEGIN
         p:= (G1 - 1) * W1; q:= 1 + p;
         p:= G1 * W1;       CcG:= p / q
       END;
     
     FUNCTION Coef_C(Pil: Byte; t: Reel): Reel;
       VAR u, v, w: Reel;
       BEGIN
         IF t>1 THEN u:= t - 2
                ELSE IF t<-1 THEN u:= t + 2
                             ELSE u:= t;
         v:= Abs(u); w:= 2 - (3 * v); IF w>1 THEN w:= 1
                                             ELSE IF w<0 THEN w:= 0;
         CASE Pil OF  0: Coef_C:= w;
                      9: Coef_C:= CcG(g, w)
                      ELSE Coef_C:= Sqrt(w)  END
    //0:     Coef_C:= w
    //1:     Coef_C:= Sqr(w)
    //2:     u:= Sqr(w); Coef_C:= Sqr(u)
    //3:     u:= Sqrt(1 - w); Coef_C:= Sqr(1 - u)
    //4:     Coef_C:= Sqrt(w)
    //5:     u:= Sqr(1 - w); Coef_C:= Sqrt(1 - u)
       END;
    C'est encore en chantier, et tu complèteras sans difficulté le bloc d'instructions.

    ... J'ai bien sûr cherché "fonction homographique", me suis retrouvé sur une page Wikipédia où j'avoue humblement n'avoir rien compris...
    L'article cité est l'exemple typique de réponse inutilement compliquée, de nature à donner des sueurs froides à tout lecteur désireux de se rafraîchir la mémoire.
    Il fallait s'en tenir aux deux premières lignes, et à la formule donnée:
    En mathématiques, une fonction homographique est une fonction qui peut être représentée sous la forme d'un quotient de deux fonctions affines ...
    f(x) = (a*x + b)/(c*x + d)

    Elle est dans le cas présent exprimée sous la forme: CcG = (g1*w1)/(1 + (g1-1)*w1) , dans laquelle (w1) croorespond à la variable (x);
    on a bien sûr: a = g1 , b = 0 , c = (g1-1) , d = 1 .

    Un aide-mémoire niveau bac t'aurait été plus utile. On en trouve sur la Toile, mais parfois de qualité douteuse (c'est le gros problème).
    Il ne faut pas négliger les ressources du site - voir ici, mais je ne sais si cela te convient.
    Je dois m'arrêter là pour l'instant. Bon courage.

  3. #43
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    Salut,

    Merci de ta grande implication, le problème c'est que tu es resté dans ton monde et que moi, j'ai atteint mes limites face à tes codes auxquels je ne comprends absolument rien, que je ne sais pas comment mettre en œuvre et qu'au final je ne sais pas ce qu'il faut en attendre...

    Plus le fait que ça ne compile jamais du premier coup et qu'il faut donc adapter, mais dans quelle direction ?
    Quand par exemple tu écris FOR x:= 1 TO La DO il me faut convertir x en integer (sinon ça ne compile pas) quand tu le déclarais en real, mais est-ce que ça ne va pas impacter des calculs ailleurs ?
    Pareil pour ton "La", puis il me faut deviner ce qui se cache sous ton Couleur_P, supposer des trucs et des machins et tenter (sans aucune idée du résultat) de remplacer tes lignes Ma[x, y+m]:= Couleur_P(Cbl) par Px[3]:= Cbl; Ma[round(x), round(y)+m]:= Px;, est-ce que c'est juste, est-ce que c'est faux ? Aucune idée mais, en cascade et au final je me retrouve avec une magnifique image noire...
    Pas vraiment le but recherché...

    Quant à ton rajout du pilote (dont je n'ai pas le moindre idée d'à quoi il peut bien servir et dont tu ne me dis rien), ben lui aussi il me balance de magnifiques images noires...

    Bref, ce soir, tout ça n'est pas glorieux...

    Citation Envoyé par wiwaxia Voir le message
    Un aide-mémoire niveau bac t'aurait été plus utile.
    Non, il m'aurait fait perdre mon temps : les maths m'ont fait décrocher de la scolarité aux alentours de la 1re, entre l'adolescence qui me faisait bouillonner le sang et les sens et l'abstraction de plus en plus avérée de l'algèbre alors que je me débrouillais très bien avec Pythagore, bon, je ne vais pas raconter ma vie, juste que ce soir je n'ai pas progressé d'un centimètre.

    Quand tu dis, en bleu,
    Citation Envoyé par wiwaxia Voir le message
    En mathématiques, une fonction homographique est une fonction qui peut être représentée sous la forme d'un quotient de deux fonctions affines ...
    je vais être honnête, ça me fait une belle jambe !, parce que 1- je ne me souviens absolument pas de ce qu'est une fonction affine, et 2- si je m'en souvenais, pourquoi diviser l'une par l'autre ? Pourquoi ne pas les multiplier, ou les soustraire, etc. ? Pas la moindre idée, pas la moindre vision.
    C'est comme en cuisine : il y a des gens ils lisent une recette (200 g de ceci, 30 cl de cela) et ils savent ce que ça va donner une fois réalisée, le goût, tout ça, alors que moi, même avec la photo je n'en ai pas la moindre idée.
    Ben en math c'est pareil : je n'ai pas la moindre idée de là où je vais.

    Cet après-midi je suis tombé sur un bout de tuto qui dessinait une courbe sinusoïdale ; pour bien l'appréhender, la saisir, pour en avoir une "vision", il a fallu que je lui change des valeurs, une à la fois, dans un sens ou dans l'autre, et je l'ai enfin captée. Tu vois le truc ?

    Mais si ça t'emm..., pas de souci, on laisse tomber.

  4. #44
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    Z_32 = type LongInt - entier signé codé sur 32 bits. Le lapsus m'est revenu en tête ce matin, mais tu avais déjà répondu.
    (x) et (y) sont des compteurs, donc nécessairement de type entier, comme ce qui s'y rattache (La, Ha).
    L'emploi d'un entier long permet d'éviter les éventuels débordements d'intervalle qui pourraient résulter d'un calcul ultérieur (par ex. celui du nombre de pixels (Np = La * Ha).

    Le type Integer est un survivant de la préhistoire, et peut dépendre (entre autres) de la machine;
    http://wiki.freepascal.org/Integer/fr
    La taille d'un entier dépend de la machine pour laquel le compilateur génère le code (32 bit ou 64 bit), du type de compilateur (16 bits, 32 bits ou 64 bits) et des paramètres passés au compilateur dans certains cas.
    http://wiki.freepascal.org/Variables_and_Data_Types/fr
    Le type integer peut contenir des entiers de -32768 à 32767. C'est une plage signée qui peut être contenue dans un un mot de 16 bits, c'est un héritage de l'époque où les CPU 16 bits étaient communes.

    Si tu y tiens absolument, il vaut mieux lui préférer le type SmallInt, bien défini.

    (La) et (Ha) sont les variables locales destinées à recevoir les valeurs de (Larg_Image) et (Haut_Image) - largeur et hauteur de l'image; la notation n'est pas quelconque.
    (Couleur_P(.)) est nécessairement de type Pixel, comme chacun des éléments de la matrice; cette fonction étant définie dans une unité, donc invisible, j'ai repris la procédure concernée selon une variante plus lourde,mais plus compréhensible:
    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
     
     PROCEDURE CalcMat_Im01(La, Ha: Z_32; VAR Ma: Tab_Pix);
       CONST Lim = 5000; h = 2 / 3; m = 10;
             Cbl: Pixel = (255, 0, 0);
             Cve: Pixel = (0, 255, 0);
             Cro: Pixel = (0, 0, 255);
       VAR k, K1, x, y: Z_32; r, s: Reel;
       BEGIN
         K1:= Round(0.45 * Ha); Dec(K1);
         FOR k:= -Lim TO Lim DO
           BEGIN
             r:= k / Lim;       s:= (r + 1) * (La - 1);
             x:= Round(s / 2);  Inc(x);
             s:= Coef_C(Pilote, r);     y:= Round(K1 * s);
             Ma[x, y+m]:= Cve;
             s:= Coef_C(Pilote, r + h); y:= Round(K1 * s);
             Ma[x, y+m]:= Cbl;
             s:= Coef_C(Pilote, r - h); y:= Round(K1 * s);
             Ma[x, y+m]:= Cro
           END
       END;
    La permutation du bleu et du rouge vient de ce que dans un fichier Bitmap les indices sont énoncés dans l'ordre (b, v, r).
    L'insertion de (y+m) en ordonnée permet d'aménager une bande noire de (m-1) liges sous les graphiques.

    (Pilote) est un paramètre de choix de fonction, cela se voit dans les instructions conditionnelles:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
         CASE Pil OF  0: Coef_C:= w;
                      9: Coef_C:= CcG(g, w)
                      ELSE Coef_C:= Sqrt(w)  END
    Pour un premier essai rudimentaire, tu peux éventuellement lui affecter une valeur constante, et de même pour le paramètre (g).

    Les pièges ne manquent pas, mais tu es jusque là parvenu à adapter les blocs d'instructions; il n'y a aucune raison pour que cela ne continue pas.
    Je poursuivrai plus tard.

  5. #45
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    Les pièges ne manquent pas, mais tu es jusque là parvenu à adapter les blocs d'instructions; il n'y a aucune raison pour que cela ne continue pas.
    Oui, hé bien là, je suis face à un mur, une muraille insurmontable, pour le moment :

    Citation Envoyé par wiwaxia Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
             Cbl: Pixel = (255, 0, 0);
             Cve: Pixel = (0, 255, 0);
             Cro: Pixel = (0, 0, 255);
    Ça, ça compile parce que c'est en constantes, mais le temps que ça m'a pris pour réaliser que ça me faisait planter plus loin, je t'explique pas !

    Mais bon, pour faire court et simple,
    Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    var
      PixelNoir: Pixel;
    begin
      PixelNoir[1]:=0;
      PixelNoir[2]:=0;
      PixelNoir[3]:=0;
    end;
    dans ce bout de procédure c'est compil OK mais Access Violation à l'exécution sur la première ligne. Or c'est typiquement le genre de construction que tu utilises. Donc là, je suis un peu comme une poule qui aurait trouvé un couteau, tu vois ?...

    J'ai bien sûr essayé directement PixelNoir := (0,0,0); mais ça ne compile pas (Syntax error, ")" expected but "," found avec le curseur qui clignote après le 1er 0 -- je ne vois pas pourquoi...), pas plus que PixelNoir := [0,0,0]; (Incompatible types: got "Set Of Byte" expected "Pixel" -- ça semble logique, donc c'est l'autre écriture qui serait bonne, la première, avec les parenthèses, mais elle est refusée et si je mets PixelNoir := (0); comme suggéré c'est direct Incompatible types: got "ShortInt" expected "Pixel" , donc vélo dans la campagne cet aprème...)

  6. #46
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    Rien de tel qu'une bonne promenade pour s'aérer les méninges.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
     
      CONST Cbl: Pixel = (255, 0, 0);
             Cve: Pixel = (0, 255, 0);
             Cro: Pixel = (0, 0, 255);
    C'est lourd et répétitif, mais il n'y a eu aucun incident lors de la compilation et du lancement du programme en version modifiée.

    De même l'affectation d'une valeur fixe à une autre variable du même type:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    var PixelNoir: Pixel;
    begin
      PixelNoir[1]:=0;
      PixelNoir[2]:=0;
      PixelNoir[3]:=0;
    end;
    équivaut à une déclaration en constante
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    CONST PixelNoir: Pixel = (0, 0, 0);
    Il faut rappeler le type d'une variable composée pour la déclarer en constante: il s'agit alors de variables initialisées.
    http://pascal.developpez.com/cours/c...?page=pg_Array (fin du chapitre)
    http://pascal.developpez.com/cours/c...pg_Const#LXXXI

    Cela doit passer aussi en Free Pascal. Je ne vois pas ce qui peut bloquer ... mais il s'agit de ton programme; je ne propose que quelques pièces détachées, et cela fonctionnait jusqu'à présent.

    # Ta phobie des maths est proprement sidérante: d'une part tu écris un programme viable de 51 lignes (hier, 12h03) dont - cerise sur le gâteau - tu détermines le temps d'exécution , d'autre part une ligne de définition te fais promptement détaler, au point d'oublier la réponse qui venait ensuite !
    Il s'agit moins de la méconnaissance d'un domaine, que d'un réflexe d'aversion acquis au cours des études.
    J'ai rencontré cette attitude chez quelques étudiants post-bac; il est difficile de s'en défaire, mais ce n'est pas insurmontable.

    J'ai retenu deux sites après un parcours sur la Toile, concernant les formulaires de Mathématiques:
    ■ un ensemble de formulaires tous niveaux, de la 6me à la Terminale
    http://www.mathovore.fr/maths-formulaire
    ■ un kit de survie, un peu hard d'après ce que j'ai vu (pour Indiana Jones à la sortie du lycée):
    http://www.xm1math.net/terminale_s/kit_term_s.pdf
    Le mieux serait que tu ailles en bibliothèque pour lire "les Maths pour les nuls", avant de l'acquérir éventuellement en librairie. Les livres de cette collection sont très bien rédigés, dans un style clair et vivant.

    # Pour cette question, c'est NON d'office - à moins que la réponse soit explicitement donnée sur un site, ou qu'un autre participant fournisse des informations précises sur le sujet -
    ... Et si on voit le bout du tunnel de tout ça, je te propose ensuite de réfléchir à la représentation des couleurs de la lumière visible ...
    parce que cela demande une incursion dans des domaines difficiles et très spécialisés:
    - l'étude de la lumière émise par les écrans;
    - la sensibilité spectrale de la rétine humaine.
    Il faudrait disposer d'une liste expérimentale de couleurs monochromatiques - donc de quadruplets (longueur d'onde, r, v, b) sur le domaine du visible (400 à 800 nm) pour construire les 3 fonctions appropriées: r = F(Lo), v = G(Lo), b = H(Lo) .
    Les schémas abondent sur la toile, mais rien ne garantit que la teinte soit correctement rendue au voisinage du point considéré.

  7. #47
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    'soir !

    J'aime bien quand les choses sont synchro, dans ce monde de fous, ça me remet de bonne humeur

    Au moment où je termine mon montage avec Gimp, le ding-dong de ma messagerie m'annonce un nouveau mail, et c'est ton post ! Tu tombes bien !

    Je m'en suis sorti de ce *$#!@§! de bug de mes deux, tu sais où il était planqué, l'animal ? Dans un dépassement de capacité, solution Tab_Pix = ARRAY[1..Dim_Max, 1..(Dim_Max div 2)] OF Pixel; le temps que ça m'a coûté, même pas je te raconte.

    Par contre, du coup, je peux te montrer ça, que je viens de démouler à l'instant, mais faudra que tu m'expliques :
    Nom : im01_im02.jpg
Affichages : 115
Taille : 10,4 Ko

    EDIT : correction, suite à relecture attentive du code de Im02 (m'étais gourré quelque part) : voilà une nouvelle image où l'on note, avec une loupe, une 1re bande verticale à gauche toute pleine de points de couleurs.
    Nom : Im02.jpg
Affichages : 138
Taille : 10,5 Ko /EDIT

    en haut un a-e-c tout bête que je suppose être la source pour construire les graphiques (tu ne m'as toujours rien expliqué de ce côté-là...), en dessous l'utilisation de la proc CalcMat_Im01 à qui je passe l'a-e-c et tout en bas la CalcMat_Im02 à qui blabla, qui est vraiment bizarre (les séparations, ce sont les deux bandes gris foncé).
    La 01 on dirait qu'il ne lui manque pas grand chose, mais je ne sais pas encore quoi, plus les couleurs qui ne sont pas à leurs bonnes places mais ça, ça sera vite réglé...
    EDIT : non, je n'arrive pas à régler "vite" ce pb de couleurs avec Im01... /EDIT

    Citation Envoyé par wiwaxia Voir le message
    # Ta phobie des maths est proprement sidérante: d'une part tu écris un programme viable de 51 lignes (hier, 12h03) dont - cerise sur le gâteau - tu détermines le temps d'exécution, d'autre part une ligne de définition te fais promptement détaler, au point d'oublier la réponse qui venait ensuite !
    Mais le temps d'exécution il est documenté sur des milliers de sites, y a pas à se prendre la tête et à réinventer la roue, c'est tout simple !

    Citation Envoyé par wiwaxia Voir le message
    Le mieux serait que tu ailles en bibliothèque pour lire "les Maths pour les nuls", avant de l'acquérir éventuellement en librairie. Les livres de cette collection sont très bien rédigés, dans un style clair et vivant.
    Plus le temps, là : je pense recevoir demain ou courant de la semaine un module électronique qui va d'abord me faire sortir le fer à souder, et me faire chauffer le clavier ensuite : il s'agit d'un convertisseur USB -> DMX pour mon fiston qui bricole dans la lumière (tiens donc !), un domaine passionnant...

    Citation Envoyé par wiwaxia Voir le message
    # Pour cette question, c'est NON d'office - à moins que la réponse soit explicitement fournie sur un site, ou qu'un autre participant fournisse des informations précises sur le sujet
    En fait, je n'ai qu'une question toute bête, mais qui m'empêche de dormir : tape donc, comme je te l'ai suggéré, "lumière visible" et contente-toi de regarder les images, tu y verras des disparités de l'une à l'autre qui font que si je voulais faire la même chose, je ne sais pas du tout laquelle choisir comme modèle, d'une part, mais d'autre part il y a une constante qui me surprend : c'est pourquoi le rouge est plus large que les autres couleurs, dans leurs images à la noix ?
    Je dis "à la noix" parce que certains représentent l'infrarouge en allant vers le noir quand d'autres vont vers le blanc, et pareil du côté de l'ultra-violet (quand il y est : certains l'omettent)

    Bon, je vais maintenant lire attentivement ce que tu m'as répondu, mais je voulais te faire découvrir l'avancement du schmilblik !

  8. #48
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    Salut,

    Je réponds sur quelques points.

    1) Première image:Nom : Im [2016-11-06] A_250x250.png
Affichages : 186
Taille : 3,8 Ko

    Tout se passe comme si au lieu d'écrire
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     ...
      K1:= Round(0.55 * Ha); 
         FOR x:= 1 TO La DO
           FOR y:= K1 TO Ha DO ... 
     
               Ma[x, y]:= Px ...
    tu avais mis
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     ...
      K1:= Round(0.55 * Ha); 
         FOR x:= 1 TO La DO
           FOR y:= K1 TO Ymax DO ...       // avec Ymax > La
     
               Ma[x, 1 + ((y-1) MOD Ha)]:= Px ...
    Il y a eu dépassement d'intervalle, et intervention du reste modulaire - que tu l'aies intentionnellement programmé, ou que le logiciel s'en soit implicitement chargé (auquel cas il est vraiment sympa !).
    De plus les deux parties du spectre sont décalées horizontalement de (1/6) de période, en haut centré sur le cyan (ton modèle), en bas sur le vert (le mien): il y a eu soit un mélange (peu probable) de formules, soit une discontinuité (encore un modulo sournois !) ...

    La partie graphique présente aussi un décalage vertical analogue (sans même parler des fonctions Coef_C(.), qui semblent se réduire à une constante (Coef_C(x) = 0 ou 1 ?); on ne voit aucun segment incliné, comme si tu avais imposé le choix dichotomique:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
           IF u>0 THEN u:= 1 ELSE u:=0
    Les termes (x) et (y) sont-ils bien indépendants ? S'agit-il bien de variables locales ? Parce que les deux parties de l'image relèvent de deux procédures différentes ... C'est assez intrigant.

    2) Seconde image: Nom : Im [2016-11-06] B_400x134.png
Affichages : 262
Taille : 4,5 Ko
    Les couleurs ont ici été décalées horizontalement, mais surtout le palier maximal a disparu, comme si tu avais codé, pour l'écrêtage de la fonction:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
      IF u>1 THEN u:= 0   // au lieu de u:= 1
    Quand aux graphiques ... ils sont peut-être cachés par le spectre (bien mal nommé dans le cas présent), que tu n'as pas propulsé dans la partie supérieure de l'image; n'aurais-tu pas écrit:
    au lieu de:
    Je ne suis malheureusement pas doué de vision extra-lucide.
    Pourquoi le raccordement pose-t-il autant de difficultés ? Un appel direct de ta variable "bmp" devrait te permettre de te passer de la matrice de pixels.

    3) La recherche sur "lumière visible" conduit à des trouvailles intéressantes; je les commenterai plus tard.

  9. #49
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    Yep !
    Citation Envoyé par wiwaxia Voir le message
    Je réponds sur quelques points.
    Moi aussi !
    On y va :

    Citation Envoyé par wiwaxia Voir le message
    Tout se passe comme si au lieu d'écrire --snip-- tu avais mis --snip--
    Je serais alors vraiment torturé du bulbe,
    Déjà que j'ai un mal de chien à comprendre, si en plus je me mets à improviser, on n'est pas rendu !

    La seule chose qui m'a posé souci, c'est ton erreur de déclaration du type Z32 qui m'a obligé, au début, à planter des round(variable_type_Z32) un peu partout, et lors de la correction j'ai oublié d'enlever certains round().
    Je viens d'enlever les derniers, c'est toujours aussi moche, je te fais grâce de l'image, il y a plus joli plus bas...

    Citation Envoyé par wiwaxia Voir le message
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
           IF u>0 THEN u:= 1 ELSE u:=0
    Ça sort d'où, ça ? Pas trouvé in the code...

    Citation Envoyé par wiwaxia Voir le message
    Les termes (x) et (y) sont-ils bien indépendants ? S'agit-il bien de variables locales ? Parce que les deux parties de l'image relèvent de deux procédures différentes ... C'est assez intrigant.
    Tutafait... Tutafait... Tutafait... Tutafait...

    Citation Envoyé par wiwaxia Voir le message
    Je ne suis malheureusement pas doué de vision extra-lucide.
    Rhôôô, mais t'es mal équipé,

    Citation Envoyé par wiwaxia Voir le message
    La recherche sur "lumière visible" conduit à des trouvailles intéressantes; je les commenterai plus tard.
    Ah ah !...

    Bon, à moi ; voilà où j'en suis :
    Nom : graphe.jpg
Affichages : 179
Taille : 15,9 Ko

    il me reste à tester avec des images moins uniformes, je bricolerai à partir de "l'étambot du navire de ligne" (la Poste est passée et mon colis n'est pas là...)

    Pour arriver à cette magnifique image, il aura suffi de ça, à qui je passe un a-e-c en source et un bête TBitmap en destination, qui sera recopié dans un TImage :

    Code pascal : 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
    procedure DessineScanlineDirect(src, dst: TBitmap);
    var
      w : integer;
      rdot,gdot,bdot: byte;
      {$IFDEF WINDOWS}
      ss,dd   :  pRGBTriple; // assumes pf24bit scanlines
      {$ELSE}
      ss,dd   :  pRGBQuad;   // assumes pf24bit scanlines
      {$ENDIF}
    begin
      ss := pRGBQuad(src.RawImage.GetLineStart(127)); // au milieu de la source
      with dst do begin
        BeginUpdate();
        for w := 0 to (Width - 1) do begin
          rdot := 255-ss[w].rgbRed;   // 0 en haut donc inverser !
          gdot := 255-ss[w].rgbGreen; // 0 en haut donc inverser !
          bdot := 255-ss[w].rgbBlue;  // 0 en haut donc inverser !
          {$IFDEF WINDOWS}
          dd := pRGBTriple(dst.RawImage.GetLineStart(xxx));
          dd[w] := je laisse les windowsiens adapter ici et ligne précédente;
          {$ELSE}
          //ss[w] contient le pixel source à analyser : c'est un point composé de
          // 3 couleurs variant de 0 à 255 à afficher sur dd[w]
          dd := pRGBQuad(dst.RawImage.GetLineStart(rdot));
          dd[w] := iRGBAtoRGBAQuad(255,0,0, 255);
          dd := pRGBQuad(dst.RawImage.GetLineStart(gdot));
          dd[w] := iRGBAtoRGBAQuad(0,255,0, 255);
          dd := pRGBQuad(dst.RawImage.GetLineStart(bdot));
          dd[w] := iRGBAtoRGBAQuad(0,0,255, 255);
          {$ENDIF}
        end;
        EndUpdate();
      end;
    end;


    Et pour en revenir aux maths, indépendamment du fait que je connais la collec' "pour les nuls" (j'ai "Les réseaux pour..." acheté début 2000), voilà ce à quoi je suis arrivé en partant d'un tuto trouvé là (page 21), que j'ai adapté à ma manière : les curseurs permettent de jouer avec l'amplitude du "signal" (on dirait l'écran d'un oscillo, hein !), son offset, et la fréquence de balayage.
    Je suis assez content :
    Nom : sinusoid.jpg
Affichages : 184
Taille : 11,7 Ko

    Mais encore une fois, j'ai suivi un de tes liens, je vois toutes ces belles formules mais je n'ai aucune idée de laquelle je devrais utiliser si je devais en utiliser une, et je ne sais pas comment la mettre en œuvre dans Lazarus.
    Pour cette image c'est le tuto qui m'a pris par la main et m'a mis sur la voie.

    Bonne journée,

  10. #50
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    La seule chose qui m'a posé souci, c'est ton erreur de déclaration du type Z32 qui m'a obligé, au début, à planter des round(variable_type_Z32) un peu partout, et lors de la correction j'ai oublié d'enlever certains round().
    Je viens d'enlever les derniers, c'est toujours aussi moche, je te fais grâce de l'image, il y a plus joli plus bas...
    Désolé que cette faute d'inattention ait produit tant de dégâts !

    Bon, à moi ; voilà où j'en suis : ...
    Enfin les bonnes fonctions ! C'est un bon redémarrage.

    ... il me reste à tester avec des images moins uniformes, je bricolerai à partir de "l'étambot du navire de ligne" ...
    C'est le moment d'introduire, dans la version initiale du programme, la fonction simplifiée suivante (les précédentes constituent un ensemble un peu artificiel):
    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
     
     FUNCTION CcG(W1: Reel): Reel;
       CONST g = 2.50;
       VAR p, q: Reel;
       BEGIN
         p:= (g - 1) * W1; q:= 1 + p;
         p:= g * W1;       CcG:= p / q
       END;
     
     FUNCTION Coef_C(Pil: Byte; t: Reel): Reel;
       VAR u, v, w: Reel;
       BEGIN
         IF t>1 THEN u:= t - 2
                ELSE IF t<-1 THEN u:= t + 2
                             ELSE u:= t;
         v:= Abs(u); w:= 2 - (3 * v); IF w>1 THEN w:= 1
                                             ELSE IF w<0 THEN w:= 0;
         Coef_C:= CcG(w)
       END;
    Il ne devrait pas y avoir de problème, car cela passe en compilation ... mais une erreur est toujours possible. Dans le doute, contacte-moi avant de torpiller ton algorithme.
    La fonction CcG(.) est paramétrée par un réel (g), dont la valeur est pour l'instant passée en constante, pour faire simple.
    Il s'agit d'un faisceau de courbes passant par les points (0,0) et (1,1); le cas (g = 1) redonne le segment rectiligne (CcG(w) = 1); le graphe se bombe vers le haut pour (g > 1), vers le bas dans le cas contraire (g < 1).
    La meilleure répartition des 6 teintes est obtenue pour (g ~ 2.50) - affaire d'appréciation personnelle.
    Et pour retrouver ton profil de bateau, utilise une suite géométrique comme
    g = 3k (k variant de -4 à +4) , ou
    g = 2k (k variant de -7 à +7) .

  11. #51
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    lol ! Tu me refais le coup d'hier, le "ding-dong" au moment où je termine ma capture d'écran !
    Citation Envoyé par wiwaxia Voir le message
    Désolé que cette faute d'inattention ait produit tant de dégâts !
    Bah, c'est comme en bagnole, tu changes de radio de station, hop !, 3 morts

    Citation Envoyé par wiwaxia Voir le message
    Enfin les bonnes fonctions ! C'est un bon redémarrage.
    Attends ! Attends ! Regarde : après avoir corrigé les derniers round(), et m'être bien battu avec le fait que sous Linux les couleurs ne sont pas (il me semble) au même endroit que sous Windows,
    tada ! :

    Nom : im_01.png
Affichages : 212
Taille : 6,4 Ko

    Le dernier point qui me chiffonnait, j'ai mis ta ligne en commentaire et la mienne dessous :
    Code pascal : 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
      PROCEDURE CalcMat_Im01(La, Ha: Z_32; VAR Ma: Tab_Pix);
        CONST Lim = 5000; h = 2 / 3; m = 10; // Lim semble être le nbre de points
              Cbl: Pixel = (255, 0, 0);
              Cve: Pixel = (0, 255, 0);
              Cro: Pixel = (0, 0, 255);
        VAR k, K1, x, y: Z_32; r, s: Real;
        BEGIN
          Pilote := 0;
          //K1:= Round(0.45 * Ha); dec(K1); // image dst occupée à moitié... :koi:
          K1:= Round(0.9 * Ha); dec(K1);
          FOR k := -Lim TO Lim DO
            BEGIN
              r:= k / Lim;       s:= (r + 1) * (La - 1);
              x:= Round(s / 2);  inc(x);// y+m crée une bande noire de (m-1) lignes sous les graphiques
              s:= iCoef_C3(Pilote, r);     y:= Round(K1 * s); Ma[x, y+m]:= Cve;
              s:= iCoef_C3(Pilote, r + h); y:= Round(K1 * s); Ma[x, y+m]:= Cbl;
              s:= iCoef_C3(Pilote, r - h); y:= Round(K1 * s); Ma[x, y+m]:= Cro;
            END
        END;
    Ta Coef_C s'appelle ici iCoef_C3, c'est mes bidouilles ("i" comme "inline" pour speeder, 3 = num de version, quand je fais des modifs -- mais au final, la 3 ressemble à la 0)

    Et une fois ce Ma rempli, plus qu'à l'afficher :
    Code pascal : 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
      with dst do begin
        BeginUpdate();
        for h := 0 to (Height - 1) do
        begin
          {$IFDEF WINDOWS}
          dd := pRGBTriple(RawImage.GetLineStart(h));
          {$ELSE}
          dd := pRGBQuad(RawImage.GetLineStart(h));
          {$ENDIF}
     
          for w := 0 to (Width - 1) do begin
           {$IFDEF WINDOWS}
            dd[w] := iRGBtoRGBTriple();
            {$ELSE}     // positions     R             G             B
            dd[w] := iRGBAtoRGBAQuad(ma[w,h][2], ma[w,h][3], ma[w,h][1], 255);
            {$ENDIF}
          end;
        end;
        EndUpdate();
      end;
    end;

    Allez, je vais voir ce que tu viens de m'apporter...

  12. #52
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    Ça se précise ... C'est maintenant ton graphique qui recouvre le spectre:
    Non, trop haut ! Il me semble avoir écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    K1:= Round(0.45 * Ha); dec(K1);
    Quelle importance ? Un ligne de plus ou de moins ... ce n'est pas la place qui fait défaut.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    CONST Lim = 5000;               // Lim semble être le nbre de points
     ... / ...
          FOR k := -Lim TO Lim DO
    Il y a (2 * Lim + 1) points; l'énumération k = {-5000 , -4999 , -4998 , ... , -2 , -1 , 0 (valeur centrale) , 1 , 2 , ... , 4999 , 5000} fournit (2*5000 + 1) = 10001 valeurs différentes.

  13. #53
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    Citation Envoyé par wiwaxia Voir le message
    le gros obstacle, ce sera le passage de (g) en variable globale, en faisant intervenir une fonction de 2 variables: CcG2(g, w); on verra comment faire le moment venu.
    Non, ça ne sera pas le plus compliqué, il suffira de passer un record qui emballera les deux variables et hop !

    Ce qui m'embête en ce moment, c'est que je n'arrive plus à retrouver mon profil de bateau pour tester ma fonction d'analyse car, au final, ces trois traits RGB, je leur vois une utilité dans un sens ou dans un autre :
    - ou bien ils sont la représentation d'une création graphique ex nihilo (les profils de bateau par ex.) ;
    - ou bien on calcule (dessine) les graphiques puis on fait dessiner une représentation esthétique (l'a-e-c par ex.) du croquis.

    Pour le moment je fonctionne dans le 1er mode (j'ai réussi à faire cracher autre chose que l'a-e-c classique à coef_C) :
    Nom : coef_c_plus_scanline.png
Affichages : 184
Taille : 4,8 Ko

    Mais on dirait qu'il reste des bugs ou autres cochonneries : les lignes horizontales du haut et du bas ne sont pas terribles...

    Citation Envoyé par wiwaxia Voir le message
    Non, trop haut ! Il me semble avoir écrit:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    K1:= Round(0.45 * Ha); dec(K1);
    Vi, et moi j'ai écrit :
    Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
          //K1:= Round(0.45 * Ha); dec(K1); // image dst occupée à moitié... :koi:
          K1:= Round(0.9 * Ha); dec(K1);
    Dit plus clairement, avec 0.45 les traits n'occupent que la moitié supérieure de l'image destinée à les afficher...

    Citation Envoyé par foetus Voir le message
    Ah, on a des observateurs discrets !
    Coucou, toi

  14. #54
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    Là, je dois m'absenter - alors rapidement:
    1) Les belles fonctions d'avant, continues et linéaires par morceaux, sont devenues discontinues et leur période a été divisée par 2: il faut renverser le second arc curviligne pour qu'il devienne descendant, et tout rentrera dans l'ordre.
    2) Je ne comprends pas tes hésitations: 1 <= y <= 0.45*Ha pour les graphiques , 0.55*Ha <= y <= Ha pour le dégradé.
    Comme pour un mur d'immeuble: les tags au rez-de-chaussée, la belle peinture au-dessus.

  15. #55
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    Bonsoir,

    Citation Envoyé par wiwaxia Voir le message
    1) Les belles fonctions d'avant, continues et linéaires par morceaux, sont devenues discontinues et leur période a été divisée par 2: il faut renverser le second arc curviligne pour qu'il devienne descendant, et tout rentrera dans l'ordre.
    Dit comme ça, ça a l'air tout simple, on verra quand j'aurai réglé ce que je vais balancer dessous...

    Citation Envoyé par wiwaxia Voir le message
    2) Je ne comprends pas tes hésitations: 1 <= y <= 0.45*Ha pour les graphiques , 0.55*Ha <= y <= Ha pour le dégradé.
    Comme pour un mur d'immeuble: les tags au rez-de-chaussée, la belle peinture au-dessus.
    En l'espèce c'est l'inverse, les tags en hauteur et la belle peinture à portée de main, enfin, c'est le code qui le fait.

    Bon, on pourrait croire, en regardant cette image (un peu réduite), que ça y est :
    Nom : combiné.jpg
Affichages : 200
Taille : 19,6 Ko mais que nenni !

    D'abord, faut savoir que pour avoir les bonnes couleurs dans le dégradé j'ai souffert le martyre (si si !, foetus, le martyre !), à tel point que si quelqu'un veut mettre les mains dans la proc Im02 il a intérêt à s'armer de patience et de courage, et à bien lire les commentaires :
    Code pascal : 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
      PROCEDURE CalcMat_Im02(La, Ha: Z_32; VAR Ma: Tab_Pix); // dégradé
        CONST Lim = 5000; h = 2 / 3; m = 255;
        VAR K1, x, y: Z_32; r, s: Real; Px: Pixel;
        BEGIN
          K1:= round(0.55 * Ha);
    //original      FOR x:= 1 TO La DO begin // rouge à 128
          FOR x:= 0 TO La-1 DO begin // rouge à 255
    //original        s:= (x - 1)/(La - 1); r:= (2 * s);// - 1; // rouge à 128
    //        s:= (x - 1)/La; r:= (2 * s);// - 1; // rouge à 128
            s:= x/(La - 1); r:= (2 * s);// - 1;  // rouge à 255
            // Px1 serait le bleu, Px2 le rouge et Px3 le vert
            s:= iCoef_C3(Pilote, r);     Px[2]:= Round(m*s);
            s:= iCoef_C3(Pilote, r - h); Px[3]:= Round(m*s);
            s:= iCoef_C3(Pilote, r + h); Px[1]:= Round(m*s);
            FOR y:= K1 TO Ha DO
                Ma[x, y]:= Px;
    //mainform.Memo1.Lines.Add(inttostr(x)+' '+inttostr(y));//+' '+floattostr(r)+' ' +inttostr(Px[1])+' '+inttostr(Px[2])+' '+inttostr(Px[3]));
          end;
        END;
    Le "- 1;" en commentaire (lignes 8, 9, 10) dans le calcul de "r" par rapport à l'original, c'est pour commencer le dégradé à rouge, et je n'ai pas trouvé d'autre manière de faire.
    Ah, wiwaxia, tu noteras que j'ai "remonté" les calculs de "s" dans la boucle avec "x", pas la peine de faire ces calculs pendant la "descente" avec "y".

    Sa copine :
    Code pascal : 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
    FUNCTION iCoef_C3(Pil: byte; t: Real): real;
    VAR u, v, w, g: Real;
      FUNCTION CcG(G1, W1: Real): Real;
        VAR p, q: Real;
        BEGIN
          p:= (G1 - 1) * W1; q:= 1 + p;
          p:= G1 * W1;       CcG:= p / q
        END;
    BEGIN
      IF t>1 THEN u:= t - 2
             ELSE IF t<-1 THEN u:= t + 2
                          ELSE u:= t;
      v:= Abs(u); w:= 2 - (3 * v);
      IF w>1 THEN w:= 1 ELSE IF w<0 THEN w:= 0;
      CASE Pil OF
        0: iCoef_C3:= w;
        1: iCoef_C3:= Sqr(w);
        2: begin u:= Sqr(w); iCoef_C3:= Sqr(u); end;
        3: begin u:= Sqrt(1 -w); iCoef_C3:= Sqr(1 - u); end;
        4: iCoef_C3:= Sqrt(w);
        5: begin u:= Sqr(1 - w); iCoef_C3:= Sqrt(1 - u); end;
        9: iCoef_C3:= CcG(g, w);
        ELSE iCoef_C3:= Sqrt(w);
      END;
    END;

    Je pense avoir réussi à identifier les pixels Px[idx] dans la matrice Ma, mais il reste un souci, un gros souci, car en zoomant très fort et en regardant en bas à gauche du dégradé on trouve ça :
    Nom : La_moins_un.jpg
Affichages : 179
Taille : 3,7 Ko

    En général, ce genre de choses je l'ai (souvent) constaté quand on n'est pas dans le bitmap, la matrice, l'image, bref quand on tape ailleurs que là où il faudrait, pour l'affichage.

    Regardez bien les commentaires dans le code posté plus haut, selon comment on démarre le balayage, la 1re colonne est d'un beau rouge franc et massif à 255 (sauf le bas, ) ou d'un rouge-marron à 128 : là, on n'est pas dans le buffer !
    C'est ce groupe de pixels au bas de la colonne qui me crée un souci car on est censé balayer de K1 à Ha, Ha étant la hauteur de l'image que je passe à la procédure... Mystère, là, car un coup de log montre que la boucle descend bien jusqu'à 256 (hauteur de l'image-cible).

    Nom : colonne_hs_si_mémo.jpg
Affichages : 181
Taille : 5,8 Ko Et en parlant de boucle et de log, un autre mystère : si j'active le log (dans un bête mémo sur la fiche), j'ai systématiquement droit à la 1re colonne pleine de caca-boudin, voir ci-contre.

    En général, quand je loggue, je me contente de recopier des données, pas de les traficoter ; alors elle sort d'où cette colonne toute moisie dont il me suffit de mettre la ligne de log en commentaire pour qu'elle disparaisse ! Encore un truc de fou...


    J'en suis là.

  16. #56
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    Yep !
    Citation Envoyé par foetus Voir le message
    Je t'avais dit de faire des interpolations linéaires entre 2 couleurs, sur les 3 composantes (rouge, bleu, verte)
    Des quoi ? Te rappelle que je suis nul en math et que ces mots ne m'inspirant aucune vision, je suis incapable de coder ce qui se cache dessous...

    Donc je te remercie pour ton code, que j'ai traduit en Pascal et que je vais mettre là-dessous pour en faire profiter la communauté :
    Code pascal : 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
    procedure TMainForm.Button6Click(Sender: TObject);
    var
      dst: TBitmap;
     
      procedure DessinByFoetus(img: TBitmap);
      var
        width, total_width, line: integer;
        aColor: TColor;
        br, bg, bb, er, eg, eb: byte;
      begin
        total_width := img.Width;
        width := (total_width div 3);
     
        //	half gradation
        br := $FF; bg := $00; bb := $00; // red
        er := $FF; eg := $FF; eb := $00; // yellow
     
        for line := 0 to (width div 2)-1 do begin
          aColor  := $00000000;
          aColor := aColor + ((bb + (((eb - bb) * line) div (width div 2))) * $10000 {/*<< 16*/});
          aColor := aColor + ((bg + (((eg - bg) * line) div (width div 2))) * $100   {/*<<  8*/});
          aColor := aColor +  (br + (((er - br) * line) div (width div 2)));
     
          img.Canvas.Brush.Color := aColor;
          img.Canvas.Pen.Color   := aColor;
     
          img.Canvas.Rectangle(line, 0, (line + 1), (line + img.Height));
        end;
     
        //	gradation
        br := $FF; bg := $FF; bb := $00; // yellow
        er := $00; eg := $FF; eb := $FF; // cyan
     
        for line := 0 to width-1 do begin
          aColor := $00000000;
          aColor := aColor + ((bb + (((eb - bb) * line) div width)) * $10000 {/*<< 16*/});
          aColor := aColor + ((bg + (((eg - bg) * line) div width)) * $100   {/*<<  8*/});
          aColor := aColor +  (br + (((er - br) * line) div width));
     
          img.Canvas.Brush.Color := aColor;
          img.Canvas.Pen.Color   := aColor;
     
          img.Canvas.Rectangle((line + (width div 2)), 0, (line + (width div 2) + 1), (line + img.Height));
        end;
     
        //	gradation
        br := $00; bg := $FF; bb := $FF; // cyan
        er := $FF; eg := $00; eb := $FF; // magenta
     
        for line := 0 to width-1 do begin
          aColor := $00000000;
          aColor := aColor + ((bb + (((eb - bb) * line) div width)) * $10000 {/*<< 16*/});
          aColor := aColor + ((bg + (((eg - bg) * line) div width)) * $100   {/*<<  8*/});
          aColor := aColor +  (br + (((er - br) * line) div width));
     
          img.Canvas.Brush.Color := aColor;
          img.Canvas.Pen.Color   := aColor;
     
          img.Canvas.Rectangle((line + (15 * width div 10)), 0, (line + (15 * width div 10) + 1), (line + img.Height));
        end;
     
        //	half gradation
        br := $FF; bg := $00; bb := $FF; // magenta
        er := $FF; eg := $00; eb := $00; // red
     
        for line := 0 to (width div 2)-1 do begin
          aColor := $00000000;
          aColor := aColor + ((bb + (((eb - bb) * line) div (width div 2))) * $10000 {/*<< 16*/});
          aColor := aColor + ((bg + (((eg - bg) * line) div (width div 2))) * $100   {/*<<  8*/});
          aColor := aColor +  (br + (((er - br) * line) div (width div 2)));
     
          img.Canvas.Brush.Color := aColor;
          img.Canvas.Pen.Color   := aColor;
     
          img.Canvas.Rectangle((line + (25 * width div 10)), 0, (line + (25 * width div 10) + 1), (line + img.Height));
        end;
      end;
     
    begin
    //setup :
      image1.Height:=256; image1.Top:=96;
      dst := TBitmap.Create;
      dst.PixelFormat := pf24bit;
      dst.SetSize(1536, 256);
    //a-e-c :
      DessinByFoetus(dst);
      //image1.Canvas.Draw(0,0, dst); // le stretch N'EST PAS pris en compte ! :aie: !
      image1.Picture.Assign(dst); // le stretch est pris en compte et les 1536 px rentrent dans 768
      dst.Free;
    end;
    Pas la peine de mettre une copie d'écran, c'est un a-e-c comme les autres, rouge-jaune-vert-cyan-bleu-magenta-rouge.

    Pour le mettre en œuvre j'ai utilisé un TImage de 768 x 256 avec la propriété Stretch basculée à True.

    Citation Envoyé par foetus Voir le message
    Et les calculs donnent du BGR et non pas du RGB
    ils s'affichent, comme dit plus haut, très bien et très correctement dans Linux...

    Mais 38 millisecondes en moyenne , contre 26 avec Scanline

  17. #57
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    Bonsoir,

    J'ai été surpris de lire les instructions:
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
          FOR x:= 0 TO La-1 DO
     ...
            FOR y:= K1 TO Ha DO
                Ma[x, y]:= Px;
    C'est embêtant pour une matrice de type Tab_Pix = ARRAY[1..Dim_Max, 1..Dim_Max] OF Pixel ... Ne resterait-il pas des pixels non initialisés ?
    Et quel sont d'ailleurs les indices du premier pixel dans la variable 'bmp' traitée par la procédure de Lazarus ? (0, 0) ou (1, 1)?

    ... mais il reste un souci, un gros souci, car en zoomant très fort et en regardant en bas à gauche du dégradé on trouve ça :
    Et on voit bien plus surprenant en modifiant le contraste ... cela vaut le détour (je n'ai aucune explication à ce sujet ... des soupçons seulement).

    @ foetus
    Je t'avais dit de faire des interpolations linéaires entre 2 couleurs, sur les 3 composantes (rouge, bleu, verte)
    C'est bien ce dont il était initialement question, les graphes des coefficients parlent d'eux-même (voir la dernière image complète produite par Jipété).

    Et il faut corriger le problème des approximations des flottants (la division par 3, ce n'est pas méchant: on va avoir soit 0 soit 1 soit 2 lignes non prises en compte)
    L'emploi des réels dans les calculs intermédiaires supprime toute dérive, dans le cas des combinaisons linéaires de pixels .

  18. #58
    Membre émérite

    Homme Profil pro
    Formation: Chimie et Physique (structure de la matière)
    Inscrit en
    Décembre 2010
    Messages
    1 333
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 78
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Formation: Chimie et Physique (structure de la matière)
    Secteur : Enseignement

    Informations forums :
    Inscription : Décembre 2010
    Messages : 1 333
    Points : 2 570
    Points
    2 570
    Billets dans le blog
    9
    Par défaut
    L'image comportant une couleur dont l'indice dépend de l'abscisse (x) du pixel, on s'affranchira des données entières en recourant à une fonction réelle d'une variable réelle u(t) telle que (t) et (u) appartiennent au domaine [0 ; 1]; il suffira d'écrire;
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    FOR x:= 1 TO La DO          // La = largeur de l'image
        BEGIN
        t:= (x - 1)/(La - 1);      // 0 <= t <= 1
        c:= Round(255*u(t))
        ...
        END;
    Tant que la fonction u(t) est continue, il n'apparaît pas d'effets indésirables sur l'image.
    C'est du moins comme cela que je vois la chose.

  19. #59
    Expert éminent sénior
    Avatar de Jipété
    Profil pro
    Inscrit en
    Juillet 2006
    Messages
    11 000
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Juillet 2006
    Messages : 11 000
    Points : 15 487
    Points
    15 487
    Par défaut
    Bonjour !

    TERMINÉ, en ce qui concerne les bugs d'affichage,

    Ce qui m'a mis la puce à l'oreille (sale bête !), c'est de voir ça
    Citation Envoyé par wiwaxia Voir le message
    C'est embêtant pour une matrice de type Tab_Pix = ARRAY[1..Dim_Max, 1..Dim_Max] OF Pixel ... Ne resterait-il pas des pixels non initialisés ?
    Indépendamment du fait que j'avais dit, il y a quelques jours, qu'il me fallait diviser par 2 ce que j'appelle la hauteur car sinon j'avais des bugs incompréhensibles de plantage avant même d'atteindre les instructions (plantage sur le begin : jamais vu avant ici !), la solution m'a sauté à la figure en voyant ton code ci-dessus : bon sang mais c'est bien sûr !
    Code pascal : Sélectionner tout - Visualiser dans une fenêtre à part
    Tab_Pix = ARRAY[0..Dim_Max-1, 0..(Dim_Max div 2)-1] OF Pixel;
    Et voilà ! (comme disent les Américains [si si !, j'vous jure !]) :

    Nom : final.jpg
Affichages : 116
Taille : 14,8 Ko (image légèrement réduite)

    Il restait une dernière blagounette planquée au tout début de la ligne rouge du graphique, où son premier point n'était pas un rouge franc du collier mais encore un truc moisi, avec le même problème de démarrage du balayage horizontal en retard. Solution dans Im01 (grâce à un coup de log pour voir les nombres) : x:= Round(s / 2)-1; inc(x); et bingo !


    Citation Envoyé par wiwaxia Voir le message
    Et quel sont d'ailleurs les indices du premier pixel dans la variable 'bmp' traitée par la procédure de Lazarus ? (0, 0) ou (1, 1)?
    (0, 0)

    Me reste plus qu'à mettre tout ça au propre, et passer à la phase 2 : dessiner les graphiques en fonction des infos analysées dans le dégradé (ça, ça commence à venir) ou, mieux, dessiner un dégradé en fonction de graphiques créés soit par les maths (aïe aïe aïe), soit à la souris en bougeant des points sur des droites R G B...

    Mais tout ça va dépendre du colis que j'attends...


    Citation Envoyé par wiwaxia Voir le message
    Et on voit bien plus surprenant en modifiant le contraste
    Attention ! Peut-être des artefacts inclus dans l'image postée et liés à la compression jpg, je l'ai déjà vécu. T'aurais dû poster une copie d'écran...

    Pour finir là-dessus, voilà ce que je voyais hier soir à pas d'heure en faisant afficher une matrice remplie de noir (c'est le coin inférieur gauche zoomé à mort) :
    Nom : marques.jpg
Affichages : 117
Taille : 5,6 Ko Bonne journée,

  20. #60
    Rédacteur/Modérateur

    Homme Profil pro
    Ingénieur qualité méthodes
    Inscrit en
    Décembre 2013
    Messages
    4 148
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Ingénieur qualité méthodes
    Secteur : Conseil

    Informations forums :
    Inscription : Décembre 2013
    Messages : 4 148
    Points : 9 614
    Points
    9 614
    Par défaut
    Interpolation linéaire :
    comprendre ces 2 mots, ou ne pas les comprendre, ce n'est pas des maths mais du français.
    Linéaire : ça veut dire qu'on trace une Ligne ... et plus précisément une ligne DROITE.
    Interpolation : l'étymologie du mot n'est pas flagrante, mais le préfixe inter est clair : il signifie ENTRE.

    Une interpolation linéaire , c'est quoi : on a 2 points A et B dessinés sur une feuille de papier, on dessine la ligne droite qui relie nos 2 points, et l'interpolation linéaire, c'est l'ensemble des points entre A et B.
    De la même façon extrapolation linéaire, ce sont les points de cette droite AB, mais qui sont à l'extérieur du segment AB (quand on rallonge la droite)

Discussions similaires

  1. des couleurs dans la console,comment faire?
    Par rockkornman dans le forum C
    Réponses: 3
    Dernier message: 09/05/2009, 01h01
  2. variable dans un libellé, comment faire ?
    Par chapeau_melon dans le forum WinDev
    Réponses: 2
    Dernier message: 02/02/2008, 00h08
  3. Réponses: 5
    Dernier message: 03/09/2007, 21h36
  4. Très long texte dans Quick Report - Comment faire ?
    Par delphi+ dans le forum Composants VCL
    Réponses: 2
    Dernier message: 21/08/2005, 23h18
  5. [Syntaxe] Un return dans un try... Comment faire ?
    Par chuky dans le forum Général Java
    Réponses: 13
    Dernier message: 14/01/2005, 11h33

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