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

Langage Delphi Discussion :

Graphisme : problème de mode de combinaisons de couleurs


Sujet :

Langage Delphi

  1. #21
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    A Andnotor :
    Comment savoir avec un booléen qu'il y avait un croisement ?
    ... effectivement... à moins de ne basculer à true que les booleans correspondant à la zone de croisement (?) ... en plus le tableau de booleans n'existe que la durée d'un tracé d'affichage ou d'effacement. Donc si je trace maintenant et que je déplace n'importe lequel des dessins plus tard je n'ai plus le tableau à moins de les mémoriser tous !!!
    ... va falloir méditer avant d'aller plus loin.

    A+.

  2. #22
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    Finalement, j'ai remplacé le tableau de booleans par un marquage formant Flag incrusté dans le BitMap :
    - lors du tracé de dispay, dans les zones de croisement je place une couleur égale à la couleur du crayon mais dont les composantes sont décalées de + 2 si elles sont inférieures à 127 et de -2 dans le cas inverse (ce changement de couleur est imperceptible à l'oeil nu).
    - et lors du tracé d'effacement, lorsque je croise cette couleur décalée son effacement s'effectue par un NotXor entre le NotXor-Décalé et cette couleur décalée. Pour plus de détail voir la sous-procédure GSPixel encapsulée dans la procedure DrawSegmentBis ci-après qui est celle de Caribensila modifiée en conséquence :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    type tTraceMode = (tmAffiche,tmEfface,tmCopy);
     
    procedure DrawSegmentBis(const BMP: TBitMap; x1,y1,x2,y2,CoulPen: Integer; TraceMode : tTraceMode); // Caribensila mod GG
    var       e,dx,dy : Integer;     //Erreur, variation en X et en Y.
              Scan0   : Integer;     //Valeur du pointeur d'entrée dans le Bitmap.
              Scan    : Integer;     //Pointeur temporaire destiné à être incrémenté.
              Bpp     : Integer;     //Byte per pixel du Bitmap.
              pCoulPen: TRGBTriple;  //Pointe sur la couleur du crayon
              pCoulDec: TRGBTriple;  //Pointe sur la couleur décalée formant Flag.
              MLS     : Integer;     //Memory Line Size (en bytes) du Bitmap.
              W,H     : Integer;     //Hauteur et largeur du Bitmap.
              CoulDec : tColor;      //Couleur = CoulPen décalée de D = 2 formant Flag
              RD,GD,BD: byte;        //Composantes de CoulDec
              clBack  : tColor;      //Couleur Arrière-plan
              clPNX   : tColor;      //Couleur NotXor de clBack avec CoulPen
              clDNX   : tColor;      //Couleur NotXor de clBack avec CoulDec
     
              procedure InitCouls;
              const     D = 2;
              var       RP,GP,BP : byte;
              begin     RP:=GetRValue(CoulPen); GP:=GetGValue(CoulPen); BP:=GetBValue(CoulPen);
                        with pCoulPen do begin rgbtRed:=RP; rgbtGreen:=GP; rgbtBlue:=BP; end;
    	            with pCoulDec do begin // CoulPen décalée de 2
                             if RP >127 then rgbtRed  :=RP-D else rgbtRed  :=RP+D;
                             if GP >127 then rgbtGreen:=GP-D else rgbtGreen:=GP+D;
                             if BP >127 then rgbtBlue :=BP-D else rgbtBlue :=BP+D;
                             RD:=rgbtRed; GD:=rgbtGreen; BD:=rgbtBlue;
                             CoulDec:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
                        end;
              end;
     
              function clNotXor(clPen,clBack : TColor) : TColor;
              //       Renvoie couleur NotXor = not (pen.color xor clBackGround)
              begin    result := not (CoulPen xor clBack); end;
     
              procedure GSPixel;
              begin     Scan := Scan0;              // Si on se trouve dans le BMP ...
                        Inc(Scan, y1*MLS + x1*Bpp); // (Peut être omis s'il n'y a pas le risque)
                        case TraceMode of
                                 tmAffiche,
                                 tmEfface : begin with pRGBTriple(Scan)^ do clBack:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
                                                  clPNX:=clNotXor(CoulPen,clBack); // NotXor simple
                                                  clDNX:=clNotXor(CoulDec,clBack); // NotXor-Décalé
                                                  if TraceMode=tmAffiche then // Mode display :
                                                  begin if clBack=CoulPen
                                                        then pRGBTriple(Scan)^:=pCoulDec // Coul Pen décalée
                                                        else // clBack <> CoulPen alors NotXor simple avec Coul Pen
                                                        begin with pRGBTriple(Scan)^ do begin
                                                                   rgbtRed  := GetRValue(clPNX);
                                                                   rgbtGreen:= GetGValue(clPNX);
                                                                   rgbtBlue := GetBValue(clPNX);
                                                              end;
                                                        end;
                                                  end else // Mode efface :
                                                  if TraceMode=tmEfface then // NotXor entre NotXor-Décalé et CoulDec
                                                  begin if clBack=CoulDec then
                                                        begin with pRGBTriple(Scan)^ do begin
                                                                   rgbtRed  :=not (GetRValue(clDNX) xor RD);
                                                                   rgbtGreen:=not (GetGValue(clDNX) xor GD);
                                                                   rgbtBlue :=not (GetBValue(clDNX) xor BD);
                                                              end;
                                                        end else // clBack <> CoulDec alors NotXor simple avec CoulPen
                                                        begin with pRGBTriple(Scan)^ do begin
                                                                   rgbtRed  := GetRValue(clPNX);
                                                                   rgbtGreen:= GetGValue(clPNX);
                                                                   rgbtBlue := GetBValue(clPNX);
                                                              end;
                                                        end;
                                                  end;
                                            end;
                                 else pRGBTriple(Scan)^:=pCoulPen; //<- pmCopy (utilisé uniquement lors d'un appel pour un tracé de finition)
                            end;
              end; // GSPixel
    begin
              // INITIALISATION DES VARIABLES :
              // NB: Ceci peut être fait ailleurs dans le code, cependant le tampon mémoire n'est pas garanti
              // comme étant cohérent (opérations GDI récentes, par exemple). Il est donc conseillé d'appeler
              // la méthode ScanLine[] après chaque opération à risque, ou avant chaque série d'accès à la
              //  mémoire afin de synchroniser le tampon.
              Scan0 := Integer(BMP.ScanLine[0]);
              MLS   := Integer(BMP.ScanLine[1]) - Scan0; //Memory Line Size
              W     := BMP.Width ;
              H     := BMP.Height;
              Bpp   := Abs(MLS div W);
    	  InitCouls;
     
              try  //DEBUT DE L'ALGO
                    dx:= x2-x1;
                    if dx<>0 then begin
                       if dx>0 then begin
                          dy:= y2-y1;
                          if dy<>0 then begin
                            if dy>0 then begin
                                if dx>=dy then begin
                                   e:= dx;
                                   dx:= e  shl 1;
                                   dy:= dy shl 1;
                                   repeat
                                     if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                     Inc(x1);
                                     e  := e - dy;
                                     if e<0 then begin
                                        Inc(y1);
                                        Inc(e,dx);
                                     end;
                                   until x1=x2;
                                end
                                else begin // dx<dy
                                     e  := dy;
                                     dy := e  shl 1;
                                     dx := dx shl 1;
                                     repeat
                                       if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                       Inc(y1);
                                       Dec(e,dx);
                                       if e < 0 then begin
                                          Inc(x1);
                                          Inc(e,dy)
                                       end;
                                     until y1 = y2;
                                end; // if dx
                            end // if dy>0
                            else begin // dy <=0
                                 if dx >= -dy then begin
                                    e  := dx;
                                    dx := e  shl 1;
                                    dy := dy shl 1;
                                    repeat
                                      if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                      Inc(x1);
                                      Inc(e,dy);
                                      if e < 0 then begin
                                         Dec(y1);
                                         Inc(e,dx);
                                      end;
                                    until x1 = x2;
                                 end // if dx >= -dy
                            else begin // dx < -dy
                                 e  := dy;
                                 dy := e  shl 1;
                                 dx := dx shl 1;
                                 repeat
                                   if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                   Dec(y1);
                                   Inc(e,dx);
                                   if e > 0 then begin
                                      Inc(x1);
                                      Inc(e,dy);
                                   end;
                                 until y1 = y2;
                            end; // dx < -dy
                          end; // if dy<>0
                       end // if dx>0
                       else begin // dx<=0
                            repeat
                               if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                               Inc(x1);
                            until x1 = x2 ;
                       end; // dx<=0
                    end
                    else begin
                         dy := y2 - y1;
                         if dy <> 0 then begin
                            if dy > 0 then begin
                               if -dx >= dy then begin
                                  e  := dx;
                                  dx := e  shl 1;
                                  dy := dy shl 1;
                                  repeat
                                    if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                    Dec(x1);
                                    Inc(e,dy);
                                    if e >= 0 then begin
                                       Inc(y1);
                                       Inc(e,dx);
                                    end
                                  until x1 = x2;   end
                               else begin // -dx < dy
                                    e  := dy;
                                    dy := e  shl 1;
                                    dx := dx shl 1;
                                    repeat
                                      if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                      Inc(y1);
                                      Inc(e,dx);
                                      if e <= 0 then begin
                                         Dec(x1);
                                         Inc(e,dy);
                                      end;
                                    until y1 = y2;
                               end; // -dx < dy
                            end //if dy > 0
                            else begin // dy <=0
                                 if dx <= dy then begin
                                    e  := dx;
                                    dx := e  shl 1;
                                    dy := dy shl 1;
                                    repeat
                                      if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                      Dec(x1);
                                      Dec(e,dy);
                                      if e >= 0 then begin
                                         Dec(y1);
                                         Inc(e,dx);
                                      end;
                                    until x1 = x2;
                                 end // if dx <= dy
                                 else begin // dx > dy
                                      e  := dy;
                                      dy := e  shl 1;
                                      dx := dx shl 1;
                                      repeat
                                        if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                        Dec(y1);
                                        Dec(e,dx);
                                        if e >= 0 then begin
                                           Dec(x1);
                                           Inc(e,dy);
                                        end;
                                      until y1 = y2;
                                 end; // dx > dy
                            end; // dy <=0
                         end //if dy <> 0
                         else begin
                              repeat
                                if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                Dec(x1);
                              until x1 = x2 ;
                         end;
                    end;
              end
              else begin
                   dy := y2 - y1;
                   if dy  <> 0 then begin
                      if dy > 0 then begin
                         repeat
                           if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                           Inc(y1);
                           until y1 = y2 ;
                      end
                      else begin
                           repeat
                             if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                             Dec(y1);
                           until y1 = y2 ;
                      end;
                   end;
              end;
        finally
        end;
    end; // DrawSegmentBis
    ... l'affichage puis l'effacement s'effectuent correctement y compris dans les zones de croisement.

    Pour le tracé d'une droite d'épaisseur supérieure à 1 avec embouts arrondis je n'ai pas utilisé DrawCircle mais je prolonge tout simplement la longueur de chaque droite parallèle épaisse d'un pixel tracée avec DrawSegmentBis appelée par la procedure DrawLine ci-après :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    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
    procedure DrawLine( BMP : TBitMap; xo,yo,xe,ye, epTrait : integer; CoulPen : TColor; TraceMode : tTraceMode);
    var       Theta,miEp,si,co,mis,mic,sinco,cosco,
              ep,x,y,dx,dy,xo1,yo1,xe1,ye1,xo2,yo2,xe2,ye2,a,b,xorMin,xerMax,yorMin,yerMax,rr,d,u : Extended;
              iy,ix,yoMin,yeMax,xoMin,xeMax,r,i,j,xoc,xec,yoc,yec : integer;
    begin     dx:=xe-xo; dy:=ye-yo;
              miep:=epTrait/2; rr:=miEp; ep:=0;
              if dx=0 then // Verticale
              begin xo1:=xo - miep; xo2:=xo + miep; yo1:=min(yo,ye); ye1:=max(yo,ye);
                    for ix:=trunc(xo1) to trunc(xo2) do begin
                        // Embouts arrondis :
                        d:=abs(rr-ep); if rr>d then u:=sqrt(sqr(rr)-sqr(d)) else u:=0;
                        yoMin:=trunc(yo1-u); yeMax:=trunc(ye1+u);
                        // Tracé du segment incluant les prolongements pour embouts arrondis :
                        DrawSegmentBis(BMP,ix,yoMin,ix,yeMax,CoulPen,TraceMode);
                        ep:=ep+1;
                    end;
                    EXIT;
              end;
              if ye=yo then // Horizontale
              begin yo1:=yo - miep; yo2:=yo + miep; xo1:=min(xo,xe); xe1:=max(xo,xe);
                    for iy:=trunc(yo1) to trunc(yo2) do begin
                        // Embouts arrondis :
                        d:=abs(rr-ep); if rr>d then u:=sqrt(sqr(rr)-sqr(d)) else u:=0;
                        xoMin:=trunc(xo1-u); xeMax:=trunc(xe1+u);
                        // Tracé du segment incluant les prolongements pour embouts arrondis :
                        DrawSegmentBis(BMP,xoMin,iy,xeMax,iy,CoulPen,TraceMode);
                        ep:=ep+1;
                    end;
                    EXIT;
              end;
              // Droites inclinées
              Theta:=arcTan2(ye-yo,xe-xo);      a:=tan(Theta);
              si:=sin(Theta);   co:=cos(Theta); mis:=miep*si;  mic:=miep*co;
              xo1:=xo + mis;    yo1:=yo - mic;  xo2:=xo - mis; yo2:=yo + mic;
              xe1:=xe + mis;    ye1:=ye - mic;  xe2:=xe - mis; ye2:=ye + mic;
              sinco:=sin(Pi/2-theta);           cosco:=cos(Pi/2-theta);
              dy:=abs(ye-yo); dx:=abs(xe-xo);
              if dy>=dx then // "y = a.x + b" --> x:= (y - b)/a
              begin yorMin:=min(yo1,ye1); yerMax:=max(yo1,ye1);
                    b:=ye1 - a*xe1; ep:=0; si:=abs(si);
                    repeat // Embouts arrondis :
                           d:=abs(rr-ep); if rr>d then u:=si*sqrt(sqr(rr)-sqr(d)) else u:=0;
                           xoc:=trunc((yorMin-u-b)/a);
                           xec:=trunc((yerMax+u-b)/a);
                           // Tracé du segment incluant les prolongements pour embouts arrondis :
                           DrawSegmentBis(BMP,xoc,trunc(yorMin-u),xec,trunc(yerMax+u),CoulPen,TraceMode);
                           if TraceMode<>tmCopy then begin
                               ep:=ep+1;
                               b:=b+1/sinco;
                               yorMin:=yorMin+sinco;
                               yerMax:=yerMax+sinco;
                           end else begin // si tmCopy alors passe de finition resserrée
                               ep:=ep+0.5;
                               b:=b+0.5/sinco;
                               yorMin:=yorMin+0.5*sinco;
                               yerMax:=yerMax+0.5*sinco;
                           end;
                    until (ep>=epTrait);
                    EXIT;
              end else // dy < dx -> y = a.x + b
              begin b:=yo1 - a*xo1; ep:=0; co:=abs(co);
                    xo2:=min(xo1,xe1); xe2:=max(xo1,xe1); xorMin:=xo2; xerMax:=xe2;
                    repeat // Embouts arrondis :
                           d:=abs(rr-ep); if rr>d then u:=co*sqrt(sqr(rr)-sqr(d)) else u:=0;
                           // Tracé du segment incluant les prolongements pour embouts arrondis :
                           yoc:=trunc(a*(xorMin-u) + b);
                           yec:=trunc(a*(xerMax+u) + b);
                           DrawSegmentBis(BMP,trunc(xorMin-u),yoc, trunc(xerMax+u),yec,CoulPen,TraceMode);
                           if TraceMode<>tmCopy then begin
                               ep:=ep+1;
                               b:=b+1/sinco;
                               xorMin:=xorMin-cosco;
                               xerMax:=xerMax-cosco;
                           end else begin // si tmCopy alors passe de finition resserrée
                               ep:=ep+0.5;
                               b:=b+0.5/sinco;
                               xorMin:=xorMin-0.5*cosco;
                               xerMax:=xerMax-0.5*cosco;
                           end;
                    until (ep>=epTrait);
              end;
    end; // DrawLine
    Pour DrawLine j'utilise de la trigo n'ayant pas réussi à remplacer ce schmilblick par des Inc et des Dec mais du coup il reste des points blancs (ou de la couleur d'arrière-plan) sur le tracé même dans le cas d'un tracé en mode tmCopy qui reproduit le mode pmCopy. Donc il reste un truc à perfectionner.

    A+.

    EDIT du 5 oct 2010 12h12 : Remplacement du code de DrawSegmentBis tenant compte des remarques faites jusqu'au 4 oct 16h20

  3. #23
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    si je puis me permettre quelques remarques

    pCoul ne sert à rien
    pCoulDec n'a pas besoin d'être un pointer, si ?

    je te propose également une petite simplification dans ton code en ajoutant ix et iy comme ci-dessous qui remplace les différents cas de dx et dy
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
     
                   dx:= x2-x1;
                    if dx >= 0 then
                      ix := +1
                    else
                    begin
                      dx := -dx;
                      ix := -1;
                    end;
                    dy := y2 - y1;
                    if dy >= 0 then
                      iy := +1
                    else
                    begin
                      dy := -dy;
                      iy := -1;
                    end;
     
                                if dx>=dy then begin
                                   e:= dx;
                                   dx:= e  shl 1;
                                   dy:= dy shl 1;
                                   repeat
                                     if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                     Inc(x1, ix);
                                     e  := e - dy;
                                     if e<0 then begin
                                        Inc(y1, iy);
                                        Inc(e,dx);
                                     end;
                                   until x1=x2;
                                end
                                else begin // dx<dy
                                     e  := dy;
                                     dy := e  shl 1;
                                     dx := dx shl 1;
                                     repeat
                                       if (x1>=0) and (x1<W) and (y1>=0) and (y1<H) then GSPixel;
                                       Inc(y1, iy);
                                       Dec(e,dx);
                                       if e < 0 then begin
                                          Inc(x1, ix);
                                          Inc(e,dy)
                                       end;
                                     until y1 = y2;
                                end;
    ainsi qu'une simplification ci-dessous
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    function clNotXor(clPen,clBack : TColor) : TColor;
              //       Renvoie couleur NotXor = not (pen.color xor clBackGround)
              var      R,G,B, RB,GB,BB : byte;
              begin    (*RB:=getRvalue(clBack);  GB:=getGvalue(clBack); BB:=getBvalue(clBack);
                       R:=not (RP xor RB);     G:=not (GP xor GB);    B:=not (BP xor BB);
                       Result:=RGB(R,G,B); *)
                       result := not (CoulPen xor clBack);
              end;
    dernière remarque, au lieu de jouer sur un décalage de couleur, pourquoi ne pas exploiter le canal alpha d'un mode 32bits ?

  4. #24
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    Merci Paul THOT pour ces remarques :
    pCoul ne sert à rien
    pCoulDec n'a pas besoin d'être un pointer, si ?
    ... pCoulDec n'en a pas besoin mais cela simplifie le code de GSPixel vu qu'on peut écrire directement pRGBTriple(Scan)^:=pCoulDec^ au lieu de faire un with pRGBTriple(Scan)^ do begin suivie des trois lignes de tranfert des composantes
    ... et je vais pareil pour pCoul.

    je te propose également une petite simplification dans ton code en ajoutant ix et iy comme ci-dessous qui remplace les différents cas de dx et dy
    ... Ok, je suis toujours pour les simplifications, je vais tenter de le faire demain (je suis scotché à mon micro depuis ce matin) en essayant de ne pas me planter car je n'ai pas potassé l'algo de Caribensila pour ce qui est du mécanisme de tracé.

    Et merci également pour la simplification de clNotXor.

    dernière remarque, au lieu de jouer sur un décalage de couleur, pourquoi ne pas exploiter le canal alpha d'un mode 32bits ?
    ... comme je n'ai jamais utilisé le canal Alpha j'ai utilisé l'astuce du décalage. Mais est-ce-que l'exploitation du canal Alpha va apporter une simplification ??? On utilise PRGBQuad(CurrentScan)^.rgbReserved pour ceci ???

    A+.

  5. #25
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Re-bonjour,

    Merci Paul THOT pour ces remarques :
    le H est à la fin, je n'ai pas de tête d'Ibis

    Citation Envoyé par Gilbert Geyer Voir le message
    ... pCoulDec n'en a pas besoin mais cela simplifie le code de GSPixel vu qu'on peut écrire directement pRGBTriple(Scan)^:=pCoulDec^ au lieu de faire un with pRGBTriple(Scan)^ do begin suivie des trois lignes de tranfert des composantes
    et donc "pRGBTriple(Scan)^ := pCoulDec" (sans ^) si pCoulDec est un TRGBTriple ... qui n'a pas besoin d'un new/dispose

    au fait, as-tu conscience que ce code ne fonctionne que pour du pf24bit et pf32bit ?

    Citation Envoyé par Gilbert Geyer Voir le message
    ... et je vais pareil pour pCoul.


    ... Ok, je suis toujours pour les simplifications, je vais tenter de le faire demain (je suis scotché à mon micro depuis ce matin) en essayant de ne pas me planter car je n'ai pas potassé l'algo de Caribensila pour ce qui est du mécanisme de tracé.

    Et merci également pour la simplification de clNotXor.

    A+.

  6. #26
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    A Paul TOTH :
    Oups, t'as déjà répondu pendant que j'ajoutais un EDIT de réponse à ta dernière remarque sur l'utilisation du canal Alpha que j'avais oubliée.

    le H est à la fin, je n'ai pas de tête d'Ibis
    ... autant pour moi...

    et donc "pRGBTriple(Scan)^ := pCoulDec" (sans ^) si pCoulDec est un TRGBTriple ... qui n'a pas besoin d'un new/dispose
    ... OK, merci.

    au fait, as-tu conscience que ce code ne fonctionne que pour du pf24bit et pf32bit ?
    ... ben oui, on n'a pas le choix si on veut bénéficier de la vitesse des Scanlines.

    A+.

  7. #27
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    oui le canal alpha c'est RGBQuad.rgbReserved
    si tu t'assures qu'il est à zéro (ou tout autre valeur d'ailleurs) au départ tu peux t'en servir pour flaguer les pixels

    en fait c'est la même chose que d'avoir un tableau de boolean (en fait de Byte) sauf qu'il est inclut dans l'image.

    et j'en reviens d'ailleurs à ma précédent proposition
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    procedure GSPixel;
    begin
      scan1 := Bitmap1.ScanLine[y]; // image d'origine
      scan2 := Bitmap2.ScanLine[y]; // image destination
      Inc(Scan1, x * bpp);
      Inc(Scan2, x * bpp);
      PCardinal(scan2)^ := not (PCardinal(scan1)^ xor PenColor); // pour pf32bits
    end;
    pour le ScanLine, rien ne t'empêche d'utiliser ScanLine dans les autres formats, cependant le pixel n'est plus au format RGBTriplet, il est codé sur 2 bytes (pf16bit), c'est un index dans la palette de couleurs (pf8bit) ou un simple bit en mode monochrome (pf1bit).

  8. #28
    Membre confirmé
    Homme Profil pro
    Santé
    Inscrit en
    Septembre 2010
    Messages
    290
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Nord (Nord Pas de Calais)

    Informations professionnelles :
    Activité : Santé
    Secteur : Santé

    Informations forums :
    Inscription : Septembre 2010
    Messages : 290
    Points : 534
    Points
    534
    Par défaut
    Pour les formats palettisés (autre que 24 et 32 bit), le problème c'est moi, c'est pas Scanline.
    Hélas, je n'ai jamais rien compris au système de palette Windows.

    Les remarques de Paul Toth (que je remercie aussi au passage pour des raisons personnelles et livresques ) m'ont fait remarquer d'autres maladresses de ma part dans le code.
    La vérification de l'appartenance du pointeur au Bitmap peut se faire plus simplement en vérifiant que celui-ci se trouve entre les pointeurs mini et maxi du Scanline.
    En outre, mon code bugue pour un Bitmap de 3 pixels de large en 24 bit lors du calcul de Bpp.
    Il faudrait donc ajouter :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Case  BMP.PixelFormat of
        pf24bit : Bpp:=3;
        pf32bit : Bpp:=4;
      else begin
        Showmessage('24 ou 32 bits uniquement !');
        Exit;
      end;
    end;
    et

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    var   PixMin,PixMax : Integer;
    ...
    if Integer(BMP.ScanLine[H-1]) < Scan0 then begin  //Si c'est un  Bottom-Up DIB...
    		PixMin := Integer(BMP.ScanLine[H-1]);
      	PixMax := Scan0 + Bpp*W - Bpp;   end
      else begin //sinon c'est un Top-Down DIB...
      	PixMin := Scan0;
        PixMax :=Integer(BMP.ScanLine[H-1]) + Bpp*W - Bpp;
    end;
    Puis le nouveau display :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    Scan := Scan0;
    Inc(Scan, y1*MLS + x1*Bpp);
    if (Scan>=PixMin) and (Scan<=PixMax) //Si on se trouve dans le BMP ...
      then pRGBTriple(Scan)^:= Col;   //TRGBTriple ! :ccool:

  9. #29
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    1) J'ai modifié le code de DrawSegmentBis qui tient compte des remarques de Paul TOTH d'hier 16h20 à l'exception de la simplification suivante :
    je te propose également une petite simplification dans ton code en ajoutant ix et iy comme ci-dessous qui remplace les différents cas de dx et dy
    ... je n'ai pas réussi à raccorder la simplification à la suite du code où je me perds dans le labyrinthe.
    ... j'ai placé ce code modifié dans mon message d'hier 15h12.

    2) Merci Paul TOTH pour la réponse concernant le canal Alpha : je vais voir si cela apporte une simplification ou une autre amélioration, en tous cas cela éclaire mes neurones.

    pour le ScanLine, rien ne t'empêche d'utiliser ScanLine dans les autres formats...
    ... pour l'instant je n'ai pas besoin des autres formats.

    3) A Caribensila :
    La vérification de l'appartenance du pointeur au Bitmap peut se faire plus simplement en vérifiant que celui-ci se trouve entre les pointeurs mini et maxi du Scanline.
    En outre, mon code bugue pour un Bitmap de 3 pixels de large en 24 bit lors du calcul de Bpp.
    Il faudrait donc ajouter : ...
    ... OK, merci je vais ajouter.

    A+.

  10. #30
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    1) A Paul TOTH : Ma tentative d'utilisation du canal Alpha :Avec le code actuel, pour les zones de croisement, je fais :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    if TraceMode=tmAffiche then // Mode display :
    begin if clBack=CoulPen
             then pRGBTriple(Scan)^:=pCoulDec // Couleur de crayon décalée pour conserver à deux unités près l'aspect visuel et éviter les "losanges blancs" au droit des croisements
             else ...
    ... Mais en utilisant le canal Alpha je peux seulement affecter à PRGBQuad(Scan)^.rgbReserved une valeur allant de 0 à 255 donc cela me permet de planter un Flag pour localiser les zones de croisement mais lors du display je souhaite conserver la couleur apparente dans les zone de croisement donc ce Flag ne me permet pas de remplacer pas à lui seul l'astuce de la couleur décalée qui forme déjà une sorte de Flag ...

    2) Mais voici le code de DrawSegmentBis modifié tenant compte des remarques de Caribensila :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    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
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    type tTraceMode = (tmAffiche,tmEfface,tmCopy);
     
    procedure DrawSegmentBis(const BMP: TBitMap; x1,y1,x2,y2,CoulPen: Integer; TraceMode : tTraceMode); 
    var       e,dx,dy : Integer;       //Erreur, variation en X et en Y.
              Scan0   : Integer;       //Valeur du pointeur d'entrée dans le Bitmap.
              Scan    : Integer;       //Pointeur temporaire destiné à être incrémenté.
              Bpp     : Integer;       //Byte per pixel du Bitmap.
              pCoulPen: TRGBTriple;    //Pointe sur la couleur du crayon
              pCoulDec: TRGBTriple;    //Pointe sur la couleur décalée formant Flag.
              MLS     : Integer;       //Memory Line Size (en bytes) du Bitmap.
              W,H     : Integer;       //Hauteur et largeur du Bitmap.
              CoulDec : tColor;        //Couleur = CoulPen décalée de D = 2 formant Flag
              RD,GD,BD: byte;          //Composantes de CoulDec
              clBack  : tColor;        //Couleur Arrière-plan
              clPNX   : tColor;        //Couleur NotXor de clBack avec CoulPen
              clDNX   : tColor;        //Couleur NotXor de clBack avec CoulDec
              PixMin,PixMax : Integer; //Bornes de l'intervalle d'appartenance du pointeur au BitMap
     
              procedure InitCouls;
              const     D = 2;
              var       RP,GP,BP : byte;
              begin     RP:=GetRValue(CoulPen); GP:=GetGValue(CoulPen); BP:=GetBValue(CoulPen);
                        with pCoulPen do begin rgbtRed:=RP; rgbtGreen:=GP; rgbtBlue:=BP; end;
    	            with pCoulDec do begin // CoulPen décalée de 2
                             if RP >127 then rgbtRed  :=RP-D else rgbtRed  :=RP+D;
                             if GP >127 then rgbtGreen:=GP-D else rgbtGreen:=GP+D;
                             if BP >127 then rgbtBlue :=BP-D else rgbtBlue :=BP+D;
                             RD:=rgbtRed; GD:=rgbtGreen; BD:=rgbtBlue;
                             CoulDec:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
                        end;
              end;
     
              function clNotXor(clPen,clBack : TColor) : TColor;
              //       Renvoie couleur NotXor = not (pen.color xor clBackGround)
              begin    result := not (CoulPen xor clBack); end;
     
              procedure GSPixel;
              begin     Scan := Scan0;
                        Inc(Scan, y1*MLS + x1*Bpp);
                        if not ((Scan>=PixMin) and (Scan<=PixMax)) then EXIT; // Si on se trouve en-dehors du BMP
                        case TraceMode of
                                 tmAffiche,
                                 tmEfface : begin with pRGBTriple(Scan)^ do clBack:=RGB(rgbtRed,rgbtGreen,rgbtBlue);
                                                  clPNX:=clNotXor(CoulPen,clBack); // NotXor simple
                                                  clDNX:=clNotXor(CoulDec,clBack); // NotXor-Décalé
                                                  if TraceMode=tmAffiche then // Mode display :
                                                  begin if clBack=CoulPen
                                                        then pRGBTriple(Scan)^:=pCoulDec // Coul Pen décalée
                                                        else // clBack <> CoulPen alors NotXor simple avec Coul Pen
                                                        begin with pRGBTriple(Scan)^ do begin
                                                                   rgbtRed  := GetRValue(clPNX);
                                                                   rgbtGreen:= GetGValue(clPNX);
                                                                   rgbtBlue := GetBValue(clPNX);
                                                              end;
                                                        end;
                                                  end else // Mode efface :
                                                  if TraceMode=tmEfface then // NotXor entre NotXor-Décalé et CoulDec
                                                  begin if clBack=CoulDec then
                                                        begin with pRGBTriple(Scan)^ do begin
                                                                   rgbtRed  :=not (GetRValue(clDNX) xor RD);
                                                                   rgbtGreen:=not (GetGValue(clDNX) xor GD);
                                                                   rgbtBlue :=not (GetBValue(clDNX) xor BD);
                                                              end;
                                                        end else // clBack <> CoulDec alors NotXor simple avec CoulPen
                                                        begin with pRGBTriple(Scan)^ do begin
                                                                   rgbtRed  := GetRValue(clPNX);
                                                                   rgbtGreen:= GetGValue(clPNX);
                                                                   rgbtBlue := GetBValue(clPNX);
                                                              end;
                                                        end;
                                                  end;
                                            end;
                                 else pRGBTriple(Scan)^:=pCoulPen; //<- pmCopy (utilisé uniquement lors d'un appel pour un tracé de finition)
                            end;
              end; // GSPixel
    begin
              // INITIALISATION DES VARIABLES :
              // NB: Ceci peut être fait ailleurs dans le code, cependant le tampon mémoire n'est pas garanti
              // comme étant cohérent (opérations GDI récentes, par exemple). Il est donc conseillé d'appeler
              // la méthode ScanLine[] après chaque opération à risque, ou avant chaque série d'accès à la
              // mémoire afin de synchroniser le tampon.
              case BMP.PixelFormat of
                   pf24bit : Bpp:=3;
                   pf32bit : Bpp:=4;
                   else begin Showmessage('24 ou 32 bits uniquement !'); EXIT; end;
              end;
     
              Scan0 := Integer(BMP.ScanLine[0]);
              MLS   := Integer(BMP.ScanLine[1]) - Scan0; //Memory Line Size
              W     := BMP.Width ;
              H     := BMP.Height;
              Bpp   := Abs(MLS div W);
              if Integer(BMP.ScanLine[H-1]) < Scan0 then begin  //Si c'est un  Bottom-Up DIB...
    	     PixMin := Integer(BMP.ScanLine[H-1]);
      	     PixMax := Scan0 + Bpp*W - Bpp;
              end else begin //sinon c'est un Top-Down DIB...
      	      PixMin := Scan0;
                  PixMax :=Integer(BMP.ScanLine[H-1]) + Bpp*W - Bpp;
              end;
     
    	  InitCouls;
     
              try  //DEBUT DE L'ALGO
                    dx:= x2-x1;
                    if dx<>0 then begin
                       if dx>0 then begin
                          dy:= y2-y1;
                          if dy<>0 then begin
                            if dy>0 then begin
                                if dx>=dy then begin
                                   e:= dx;
                                   dx:= e  shl 1;
                                   dy:= dy shl 1;
                                   repeat
                                     GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                                     Inc(x1);
                                     e  := e - dy;
                                     if e<0 then begin
                                        Inc(y1);
                                        Inc(e,dx);
                                     end;
                                   until x1=x2;
                                end
                                else begin // dx<dy
                                     e  := dy;
                                     dy := e  shl 1;
                                     dx := dx shl 1;
                                     repeat
                                       GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                                       Inc(y1);
                                       Dec(e,dx);
                                       if e < 0 then begin
                                          Inc(x1);
                                          Inc(e,dy)
                                       end;
                                     until y1 = y2;
                                end; // if dx
                            end // if dy>0
                            else begin // dy <=0
                                 if dx >= -dy then begin
                                    e  := dx;
                                    dx := e  shl 1;
                                    dy := dy shl 1;
                                    repeat
                                      GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                                      Inc(x1);
                                      Inc(e,dy);
                                      if e < 0 then begin
                                         Dec(y1);
                                         Inc(e,dx);
                                      end;
                                    until x1 = x2;
                                 end // if dx >= -dy
                            else begin // dx < -dy
                                 e  := dy;
                                 dy := e  shl 1;
                                 dx := dx shl 1;
                                 repeat
                                   GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                                   Dec(y1);
                                   Inc(e,dx);
                                   if e > 0 then begin
                                      Inc(x1);
                                      Inc(e,dy);
                                   end;
                                 until y1 = y2;
                            end; // dx < -dy
                          end; // if dy<>0
                       end // if dx>0
                       else begin // dx<=0
                            repeat
                               GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                               Inc(x1);
                            until x1 = x2 ;
                       end; // dx<=0
                    end
                    else begin
                         dy := y2 - y1;
                         if dy <> 0 then begin
                            if dy > 0 then begin
                               if -dx >= dy then begin
                                  e  := dx;
                                  dx := e  shl 1;
                                  dy := dy shl 1;
                                  repeat
                                    GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                                    Dec(x1);
                                    Inc(e,dy);
                                    if e >= 0 then begin
                                       Inc(y1);
                                       Inc(e,dx);
                                    end
                                  until x1 = x2;   end
                               else begin // -dx < dy
                                    e  := dy;
                                    dy := e  shl 1;
                                    dx := dx shl 1;
                                    repeat
                                      GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                                      Inc(y1);
                                      Inc(e,dx);
                                      if e <= 0 then begin
                                         Dec(x1);
                                         Inc(e,dy);
                                      end;
                                    until y1 = y2;
                               end; // -dx < dy
                            end //if dy > 0
                            else begin // dy <=0
                                 if dx <= dy then begin
                                    e  := dx;
                                    dx := e  shl 1;
                                    dy := dy shl 1;
                                    repeat
                                      GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                                      Dec(x1);
                                      Dec(e,dy);
                                      if e >= 0 then begin
                                         Dec(y1);
                                         Inc(e,dx);
                                      end;
                                    until x1 = x2;
                                 end // if dx <= dy
                                 else begin // dx > dy
                                      e  := dy;
                                      dy := e  shl 1;
                                      dx := dx shl 1;
                                      repeat
                                        GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                                        Dec(y1);
                                        Dec(e,dx);
                                        if e >= 0 then begin
                                           Dec(x1);
                                           Inc(e,dy);
                                        end;
                                      until y1 = y2;
                                 end; // dx > dy
                            end; // dy <=0
                         end //if dy <> 0
                         else begin
                              repeat
                                GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                                Dec(x1);
                              until x1 = x2 ;
                         end;
                    end;
              end
              else begin
                   dy := y2 - y1;
                   if dy  <> 0 then begin
                      if dy > 0 then begin
                         repeat
                           GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                           Inc(y1);
                           until y1 = y2 ;
                      end
                      else begin
                           repeat
                             GSPixel; // Display sauf si on se trouve en-dehors du BitMap
                             Dec(y1);
                           until y1 = y2 ;
                      end;
                   end;
              end;
        finally
        end;
    end; // DrawSegmentBis
    Au stade actuel d'avancement la procedure DrawSegmentBis ne m'inquiète pas par contre la procedure DrawLine( BMP : TBitMap; xo,yo,xe,ye, epTrait : integer; CoulPen : TColor; TraceMode : tTraceMode) qui utilise la précédente est très perfectible car car même en mode tmCopy le tracé d'un trais épais reste parsemé de points "blancs" ou de la couleur d'arrière-plan du fait que j'y utilise de la trigo que je n'ai pas réussi à remplacer par des Inc et des Dec rendant les pixels colorés jointifs sans "trous".

    A+.

  11. #31
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    euh...si tu exploites le canal alpha, tu n'a plus besoin du ta couleur décalée...
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if PRGBQuad(scan)^.rgnReserved = 0 then
    begin
      PCardinal(scan)^ := not (PCardinal(scan)^ XOR colPen);
    end;
    si je ne dis pas de bêtises, le NOT basculera déjà le canal Alpha à $FF, donc y'a rien à faire de plus

    et pour effacer tu testes que le canal alpha soit $FF du coup


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     
    if PRGBQuad(scan)^.rgnReserved = $FF then
    begin
      PCardinal(scan)^ := not (PCardinal(scan)^ XOR colPen);
    end;
    ce qui repasse le canal alpha à 0

  12. #32
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    Paul TOTH
    euh...si tu exploites le canal alpha, tu n'a plus besoin du ta couleur décalée...
    ... bigre! cela m'intrigue, mais je vais essayer car si cela marche il y aura une simplification.

    A+.

  13. #33
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    Je viens d'essayer, mais mon compilo n'est pas d'accord avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if PRGBQuad(scan)^.rgbReserved = 0 then begin
       PCardinal(scan)^ := not (PCardinal(scan)^ XOR coulPen);
    end;
    ... mon compilo m'a dit PCardinal non déclaré (Delphi-5)
    ... et vu la syntaxe que tu as utilisée ci-dessus j'ai donc décalré une variable locale : var PCardinal : PRGBQuad;
    ... mai le compilo n'en veut pas non plus en disant "[Erreur] .... : Opérateur ou point-virgule manquant" en placant le caret à la position marquée ci-après le I rouge PCardinal(Iscan)^ ... mystère et boule de gomme.

    A+.

  14. #34
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Citation Envoyé par Gilbert Geyer Voir le message
    Re-bonjour,

    Je viens d'essayer, mais mon compilo n'est pas d'accord avec :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    if PRGBQuad(scan)^.rgbReserved = 0 then begin
       PCardinal(scan)^ := not (PCardinal(scan)^ XOR coulPen);
    end;
    ... mon compilo m'a dit PCardinal non déclaré (Delphi-5)
    ... et vu la syntaxe que tu as utilisée ci-dessus j'ai donc décalré une variable locale : var PCardinal : PRGBQuad;
    ... mai le compilo n'en veut pas non plus en disant "[Erreur] .... : Opérateur ou point-virgule manquant" en placant le caret à la position marquée ci-après le I rouge PCardinal(Iscan)^ ... mystère et boule de gomme.

    A+.
    perdu ! ^^

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    type
      PCardinal = ^Cardinal;
    ben oui, une couleur 32bits c'est un Cardinal (ou un Integer)...ou un TRGBQuad qui fait aussi 32bits mais sous la forme de 4 Byte (R, G, B et A)

    dans ton code tu décomposes la couleur en R, G et B mais en fait les opérations binaires XOR et NOT peuvent être appliquées directement sur le Cardinal. Les 3 opérations (ou 4 avec l'alpha) se faisant en parallèle sur 32 bits au lieu de le faire en 3 (ou 4 fois) sur 8 bits

    je repense toujours à mes cours de pneumatique et de logique câblée (terminale E) quand je fais du binaire...on jouait avec des tubes et des clapets pour faire monter ou descendre un piston

    donc 32 bits c'est 4 tubes (de 8 bits), soit tu appliques un opérateur 32 bits (PenColor)...une sorte de domino à 4 trous sur tes 4 tubes...soit tu sépares tes 4 tubes et tu places un opérateur à un trou sur chaque tube pour ensuite remettre tes tubes ensembles...ce qui est un peu con vu que l'ordre des tubes ne change pas

    quand tu fais du SHR ou SHL tu peux avoir à dédoubler le tube ... sauf sur un multiple de 8 bits (au quel cas c'est juste un changement de tube)....

    bon j'arrête avec mes tubes, mais je trouve toujours plus facile d'avoir des représentions imagées, voir naïves, d'un problème pour le maîtriser

    le prochaine fois je vous ferais un cours sur la fragmentation avec une boîte de lego HAHA !

  15. #35
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-boujour,

    Merci Paul TOTH pour :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    type
      PCardinal = ^Cardinal;
    ainsi que pour l'explication avec les tubes.

    mais je trouve toujours plus facile d'avoir des représentions imagées, voir naïves, d'un problème pour le maîtriser
    ... absolument d'accord.

    Bon je vais essayer pour voir ce que cela donne au droit des croisements.

    A+.

  16. #36
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    Bon, le PCardinal a été accepté par le compilo et j'ai modifié le code de GSPixel comme suit :
    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
    procedure GSPixel;
              begin     Scan := Scan0;
                        Inc(Scan, y1*MLS + x1*Bpp);
                        if not ((Scan>=PixMin) and (Scan<=PixMax)) then EXIT; // Si on se trouve en-dehors du BMP
                        case TraceMode of
                                 tmAffiche,
                                 tmEfface : begin if PRGBQuad(scan)^.rgbReserved = 0 then begin // Mode display
                                                     PCardinal(scan)^ := not (PCardinal(scan)^ XOR coulPen);
                                                  end else // sans le else pas d'effacement
                                                  if PRGBQuad(scan)^.rgbReserved = $FF then begin // Mode efface :
                                                     PCardinal(scan)^ := not (PCardinal(scan)^ XOR coulPen);
                                                  end;
                                            end;
                                 else PRGBQuad(Scan)^:=pCoulPen; //<- pmCopy (utilisé uniquement lors d'un appel pour un tracé de finition)
                            end;
              end; // GSPixel
    Par contre le résultat laisse à désirer vu les copies d'écran suivantes où l'on peut constater que l'effacement est incomplet...
    En plus sur la miniature du rendu au Click de Display pour ce qui concerne les couleurs de la croix du bas l'un des traits est censé être en clGreen et l'autre en clNavy : mystère et boule de gomme.

    A+.

    EDIT du 14/10/2010 : supprimé les *.jpg pour préserver le quota de pièces jointes.

  17. #37
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
     case TraceMode of
       tmAffiche : if PRGBQuad(scan)^.rgbReserved = 0 then 
                         PCardinal(scan)^ := not (PCardinal(scan)^ XOR coulPen);
        tmEfface : if PRGBQuad(scan)^.rgbReserved = $FF then 
                         PCardinal(scan)^ := not (PCardinal(scan)^ XOR coulPen);
        else PRGBQuad(Scan)^:=pCoulPen; //<- pmCopy (utilisé uniquement lors d'un appel pour un tracé de finition)
      end;

  18. #38
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Re-bonjour,

    Merci Paul TOTH je viens d'essayer ta modification mais il n'y a pas beaucoup de changement vu les deux captures d'écran ci-jointes : effacement incomplet.

    Bon je crois que vais arrêter de te déranger avec ce sujet et retenir l'astuce des couleurs décalées vu qu'elle marche.

    A+.

    EDIT du 14/10/2010 : supprimé les *.jpg pour préserver le quota de pièces jointes

  19. #39
    Expert éminent sénior
    Avatar de Paul TOTH
    Homme Profil pro
    Freelance
    Inscrit en
    Novembre 2002
    Messages
    8 964
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 55
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Freelance
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2002
    Messages : 8 964
    Points : 28 457
    Points
    28 457
    Par défaut
    tu peux pas poster le projet qui fait ça ? qu'on regarde ce qui merdoie ?

  20. #40
    Modérateur

    Homme Profil pro
    Ingénieur retraité
    Inscrit en
    Octobre 2005
    Messages
    2 396
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur retraité

    Informations forums :
    Inscription : Octobre 2005
    Messages : 2 396
    Points : 3 266
    Points
    3 266
    Par défaut
    Bonjour,

    Paul TOTH : tu peux pas poster le projet qui fait ça ? qu'on regarde ce qui merdoie ?
    :
    ... OK, je vais extraire les bouts de code en question de mon appli et créer un projet distinct.

    A+.

+ Répondre à la discussion
Cette discussion est résolue.
Page 2 sur 4 PremièrePremière 1234 DernièreDernière

Discussions similaires

  1. Réponses: 0
    Dernier message: 03/10/2007, 13h11
  2. form en mode continu et detail couleur
    Par lolothom dans le forum VBA Access
    Réponses: 5
    Dernier message: 20/07/2007, 10h31
  3. Problème "ON_CONTROL_RANGE" mode release
    Par BoyzInDaProject dans le forum MFC
    Réponses: 5
    Dernier message: 11/05/2007, 17h24
  4. Problèmes en mode Debug
    Par pracede2005 dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 03/05/2007, 16h29
  5. problème en mode release
    Par Polux95 dans le forum Qt
    Réponses: 20
    Dernier message: 25/04/2007, 09h58

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