Les Snippets

Connexion

AntiAliasing

Niveau requis pour utiliser/comprendre cette source : 1 ( Débutant )
Créé le 22/06/2008 18:54:50 et initié par cirec [Liste]
Date de mise à jour : 30/06/2008 18:36:29
Vue : 2077
Catégorie(s) : Graphique
Langages dispo pour ce code :
- Delphi 5
- Delphi 5



Langage : Delphi 5
Date ajout : 22/06/2008
Posté par cirec [Liste]
DateMAJ : 30/06/2008

{ 
Originally written by Horst Kniebusch, modified by  alioth to make it(alot) faster.  
http://www.swissdelphicenter.ch/torry/showcode.php?id=1484 
Modifier par  Cirec permettant un résultat jusqu'a 4 fois plus rapide 
que la version  "optimisée" de Alioith (ceci en fonction de l'image bien sur)  
 30/06/2008 : Ajout de la division en début donc un gain de temps  supplémentaire 
 grâce à f0xi ... j'l'avais même pas vu ... pfff ^^  
} 
Procedure  crAntialiasing(aBitmap: TBitmap;Const  Percent: Integer = 5; Const pRect: PRect); 
Type  
  TRGBTripleArray = Array[0..32767] Of TRGBTriple; 
  PRGBTripleArray =  ^TRGBTripleArray; 
Const iCent = 20; 
Var  
  PrevLine, CurrLine, NextLine: PRGBTripleArray; 
  M, L, P :  Integer; 
  aRect, bRect: TRect; 
  nCent: Single; 
Begin 
  If aBitmap.Empty Then 
    Exit; 
  aBitmap.PixelFormat :=  pf24Bit; 
  // evite l'appel de Invalidate si Bitmap  est contenu dans un TImage 
  aBitmap.Canvas.Pixels[1, 1] :=  aBitmap.Canvas.Pixels[1, 1]; 
  bRect := Rect(1, 1, aBitmap.Width-2,  aBitmap.Height-2); 
  If  pRect = Nil  Then 
    aRect :=  bRect 
  Else 
  Begin 
    aRect :=  pRect^; 
    If aRect.Left < bRect.Left  Then 
      aRect.Left := bRect.Left;  
    If aRect.Top < bRect.Top Then 
      aRect.Top := bRect.Top; 
    If aRect.Right > bRect.Right+2 Then  
      aRect.Right := bRect.Right+2;  
    If aRect.Bottom >  bRect.Bottom+2 Then  
      aRect.Bottom := bRect.Bottom+2;  
  End; 
  nCent := iCent / (Percent +  iCent); 
  For L := aRect.Top To aRect.Bottom Do  
    Begin 
        //Over Get previous  ScanLine 
        m := l - 1;  
      PrevLine := aBitmap.ScanLine[m]; 
      //Middle Get current ScanLine 
      CurrLine :=  aBitmap.ScanLine[l]; 
        //Under Get Next  ScanLine 
        m := l + 1;  
      NextLine := aBitmap.ScanLine[m]; 
      For  P := aRect.Left To aRect.Right  Do 
      Begin 
        // Left change previous pixel //maque le moins 1  (-1) 
          m := p - 1;  
        If (CurrLine[p].rgbtRed <>  CurrLine[m].rgbtRed) Or  
           (CurrLine[p].rgbtGreen <> CurrLine[m].rgbtGreen)  Or 
           (CurrLine[p].rgbtBlue  <> CurrLine[m].rgbtBlue)Then 
        Begin  
          CurrLine[m].rgbtRed := Round(CurrLine[p].rgbtRed +  (CurrLine[m].rgbtRed - CurrLine[p].rgbtRed) * nCent);  
          CurrLine[m].rgbtGreen := Round(CurrLine[p].rgbtGreen +  (CurrLine[m].rgbtGreen - CurrLine[p].rgbtGreen) * nCent);  
          CurrLine[m].rgbtBlue := Round(CurrLine[p].rgbtBlue +  (CurrLine[m].rgbtBlue - CurrLine[p].rgbtBlue) * nCent); 
        End; 
        //Right  change next pixel 
          m := p + 1; 
        If  (CurrLine[p].rgbtRed <> CurrLine[m].rgbtRed) Or 
           (CurrLine[p].rgbtGreen <>  CurrLine[m].rgbtGreen) Or  
           (CurrLine[p].rgbtBlue <>  CurrLine[m].rgbtBlue)Then 
        Begin  
          CurrLine[m].rgbtRed := Round(CurrLine[p].rgbtRed +  (CurrLine[m].rgbtRed - CurrLine[p].rgbtRed) * nCent);  
          CurrLine[m].rgbtGreen := Round(CurrLine[p].rgbtGreen +  (CurrLine[m].rgbtGreen - CurrLine[p].rgbtGreen) * nCent);  
          CurrLine[m].rgbtBlue := Round(CurrLine[p].rgbtBlue +  (CurrLine[m].rgbtBlue - CurrLine[p].rgbtBlue) * nCent); 
        End; 
        //Under  Change pixel in previous Line 
        If  (CurrLine[p].rgbtRed <> PrevLine[P].rgbtRed) Or 
           (CurrLine[p].rgbtGreen <>  PrevLine[P].rgbtGreen) Or  
           (CurrLine[p].rgbtBlue <>  PrevLine[P].rgbtBlue)Then 
        Begin  
          PrevLine[P].rgbtRed := Round(CurrLine[p].rgbtRed +  (PrevLine[P].rgbtRed - CurrLine[p].rgbtRed) * nCent);  
          PrevLine[P].rgbtGreen := Round(CurrLine[p].rgbtGreen +  (PrevLine[P].rgbtGreen - CurrLine[p].rgbtGreen) * nCent);  
          PrevLine[P].rgbtBlue := Round(CurrLine[p].rgbtBlue +  (PrevLine[P].rgbtBlue - CurrLine[p].rgbtBlue) * nCent); 
        End; 
        //Over  Change pixel in next Line 
        If  (CurrLine[p].rgbtRed <> NextLine[P].rgbtRed) Or 
           (CurrLine[p].rgbtGreen <>  NextLine[P].rgbtGreen) Or  
           (CurrLine[p].rgbtBlue <> NextLine[P].rgbtBlue)Then 
        Begin  
          NextLine[P].rgbtRed := Round(CurrLine[p].rgbtRed +  (NextLine[P].rgbtRed - CurrLine[p].rgbtRed) * nCent);  
          NextLine[P].rgbtGreen := Round(CurrLine[p].rgbtGreen +  (NextLine[P].rgbtGreen - CurrLine[p].rgbtGreen) * nCent);  
          NextLine[P].rgbtBlue := Round(CurrLine[p].rgbtBlue +  (NextLine[P].rgbtBlue - CurrLine[p].rgbtBlue) * nCent); 
        End; 
      End; 
    End;  
End; 


Remarque :
pour une démo en situation:
http://www.delphifr.com/codes/TEXTE-GRAPHIQUE-AVEC-CONTOUR-OMBRE-TEXTURE-API-VERSION_47063.aspx

Comment ai-je pu oublier cette p..in de division ... effectivement il y a gain de temps ... Merci à f0xi ^^
c'est vrai que c'est plus un flou  mais c'est la seule que j'ai trouvé et (de 1 à 15) ça fait presque Antialiasing ^^
Langage : Delphi 5
Date ajout : 29/06/2008
Posté par f0xi [Liste]
DateMAJ : 29/06/2008
 type
    TPixel = record
      R,G,B: byte;
    end;
    pPixelArray =  ^TPixelArray;
    TPixelArray = Array[0..32767] Of TPixel;
 
  procedure AAS(aBitmap: TBitmap; const pR: PRect; const Percent: single = 0.1);
  var
    PreLn,
    CurLn,
    NexLn  : PPixelArray;
    M,
    L,
    P      : Integer;
    aRect,
    bRect  : TRect;
    nCent  : single;
  const
    iCent = 0.20;
  begin
    if aBitmap.Empty then
      Exit;
 
    aBitmap.PixelFormat := pf24bit;
 
    bRect.Left   := 1;
    bRect.Top    := 1;
    bRect.Right  := aBitmap.Width-2;
    bRect.Bottom := aBitmap.Height-2;
    aRect        := bRect;
    if pR <> Nil then
    begin
      aRect :=  pR^;
      if aRect.Left < bRect.Left then
        aRect.Left := bRect.Left;
      if aRect.Top < bRect.Top then
        aRect.Top := bRect.Top;
      if aRect.Right > bRect.Right then
        aRect.Right := bRect.Right;
      if aRect.Bottom > bRect.Bottom then
        aRect.Bottom := bRect.Bottom;
    end;
 
    nCent := iCent/(Percent + iCent);
 
    for L := aRect.Top to aRect.Bottom do
    begin
      PreLn := aBitmap.ScanLine[l-1];
      CurLn := aBitmap.ScanLine[l];
      NexLn := aBitmap.ScanLine[l+1];
 
      for P := aRect.Left to aRect.Right do
      begin
        m := p - 1;
        if (CurLn[p].R <> CurLn[m].R) or (CurLn[p].G <> CurLn[m].G) or (CurLn[p].B <> CurLn[m].B) then
        begin
          CurLn[m].R := Round(CurLn[p].R + (CurLn[m].R - CurLn[p].R) * nCent);
          CurLn[m].G := Round(CurLn[p].G + (CurLn[m].G - CurLn[p].G) * nCent);
          CurLn[m].B := Round(CurLn[p].B + (CurLn[m].B - CurLn[p].B) * nCent);
        end;
 
        m := p + 1;
        if (CurLn[p].R <> CurLn[m].R) or (CurLn[p].G <> CurLn[m].G) or (CurLn[p].B <> CurLn[m].B) then
        begin
          CurLn[m].R := Round(CurLn[p].R + (CurLn[m].R - CurLn[p].R) * nCent);
          CurLn[m].G := Round(CurLn[p].G + (CurLn[m].G - CurLn[p].G) * nCent);
          CurLn[m].B := Round(CurLn[p].B + (CurLn[m].B - CurLn[p].B) * nCent);
        end;
 
        if (CurLn[p].R <> PreLn[P].R) or (CurLn[p].G <> PreLn[P].G) or (CurLn[p].B <> PreLn[P].B) then
        begin
          PreLn[P].R := Round(CurLn[p].R + (PreLn[P].R - CurLn[p].R) * nCent);
          PreLn[P].G := Round(CurLn[p].G + (PreLn[P].G - CurLn[p].G) * nCent);
          PreLn[P].B := Round(CurLn[p].B + (PreLn[P].B - CurLn[p].B) * nCent);
        end;
 
        if (CurLn[p].R <> NexLn[P].R) or (CurLn[p].G <> NexLn[P].G) or (CurLn[p].B <> NexLn[P].B) then
        begin
          NexLn[P].R := Round(CurLn[p].R + (NexLn[P].R - CurLn[p].R) * nCent);
          NexLn[P].G := Round(CurLn[p].G + (NexLn[P].G - CurLn[p].G) * nCent);
          NexLn[P].B := Round(CurLn[p].B + (NexLn[P].B - CurLn[p].B) * nCent);
        end;
      end;
    end;
  end;         
Remarque :
methode quasi identique, mais 40% plus performante (de 20000 a 60000 cycles en moins) et plus precise dans le reglage du pourcentage d'AAS (1.0 = 100%, 0.05 = 5%, 0.0585 = 5.85%). Cette methode est plutot un filtre de Flou que de veritable anti-alias.



Codes sources en rapport avec : Antialiasing

{Visual Basic, VB6, VB.NET, VB 2005} LISSER LE TEXTE DE N'IMPORTE QUEL CONTRÔLE
Bonjour à tous, Voici un bout de code qui permet de lisser la fonte d'une fenêtre. La copie d'éc...

{PHP} SMOOTH 3D CAMEMBERT
Suite à la remarque de BADOUX concernant le "camembert" de la source N°34131 d'adresse : http://www...

{Visual Basic, VB6, VB.NET, VB 2005} POINTS ET LIGNES AVEC ANTIALIAS (LIGNES "LISSÉES"/ANTICRÈNELÉES)
Bonjour à tous, encore moi. Bon je ne me souviens plus qu'est ce qui m'a motivé à faire cette sou...

{Visual Basic, VB6, VB.NET, VB 2005} ZOOM AMÉLIORE AVEC ANTI-ALIASING
Je n'ai pas trouvé qu'équivalent sur ce site donc j'en profite pour poster cette source. Il s'agi...

{Visual Basic, VB6, VB.NET, VB 2005} LISSAGE DE COURBES
Avant tout, définir les variable suivantes: Private Type POINTAPI X As Long Y As Long ...

{Visual Basic, VB6, VB.NET, VB 2005} LISSAGE D'UN POINT, D'UN TRAIT OU D'UN CERCLE
Ce code est très utile pour imiter GIMP ou Photoshop en matière de lissage : lissage d'un trait, d'u...