{
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;