24 julio 2007

Aplicar antialiasing a una imagen

El algoritmo antialiasing se suele aplicar a una imagen para evitar los bordes dentados y los degradados bruscos de color. Lo que hace es suavizar toda la imagen.

En este caso el siguiente procedimiento toma un objeto TImage como primer parámetro y como segundo el porcentaje de antialiasing deseado, siendo normal no aplicar más del 10 o 20%:

procedure Antialiasing( Imagen: TImage; iPorcentaje: Integer );
type
TRGBTripleArray = array[0..32767] of TRGBTriple;
PRGBTripleArray = ^TRGBTripleArray;
var
SL, SL2: PRGBTripleArray;
l, m, p: Integer;
R, G, B: TColor;
R1, R2, G1, G2, B1, B2: Byte;
begin
with Imagen.Canvas do
begin
Brush.Style := bsClear;
Pixels[1, 1] := Pixels[1, 1];

for l := 0 to Imagen.Height - 1 do
begin
SL := Imagen.Picture.Bitmap.ScanLine[l];

for p := 1 to Imagen.Width - 1 do
begin
R1 := SL[p].rgbtRed;
G1 := SL[p].rgbtGreen;
B1 := SL[p].rgbtBlue;

if (p < 1) then
m := Imagen.Width
else
m := p - 1;

R2 := SL[m].rgbtRed;
G2 := SL[m].rgbtGreen;
B2 := SL[m].rgbtBlue;

if ( R1 <> R2 ) or ( G1 <> G2 ) or ( B1 <> B2 ) then
begin
R := Round( R1 + ( R2 - R1 ) * 50 / ( iPorcentaje + 50 ) );
G := Round( G1 + ( G2 - G1 ) * 50 / ( iPorcentaje + 50 ) );
B := Round( B1 + ( B2 - B1 ) * 50 / ( iPorcentaje + 50 ) );
SL[m].rgbtRed := R;
SL[m].rgbtGreen := G;
SL[m].rgbtBlue := B;
end;

if ( p > Imagen.Width - 2 ) then
m := 0
else
m := p + 1;

R2 := SL[m].rgbtRed;
G2 := SL[m].rgbtGreen;
B2 := SL[m].rgbtBlue;

if ( R1 <> R2 ) or ( G1 <> G2 ) or ( B1 <> B2 ) then
begin
R := Round( R1 + ( R2 - R1 ) * 50 / ( iPorcentaje + 50 ) );
G := Round( G1 + ( G2 - G1 ) * 50 / ( iPorcentaje + 50 ) );
B := Round( B1 + ( B2 - B1 ) * 50 / ( iPorcentaje + 50 ) );
SL[m].rgbtRed := R;
SL[m].rgbtGreen := G;
SL[m].rgbtBlue := B;
end;

if ( l < 1 ) then
m := Imagen.Height - 1
else
m := l - 1;

SL2 := Imagen.Picture.Bitmap.ScanLine[m];
R2 := SL2[p].rgbtRed;
G2 := SL2[p].rgbtGreen;
B2 := SL2[p].rgbtBlue;

if ( R1 <> R2 ) or ( G1 <> G2 ) or ( B1 <> B2 ) then
begin
R := Round( R1 + ( R2 - R1 ) * 50 / ( iPorcentaje + 50 ) );
G := Round( G1 + ( G2 - G1 ) * 50 / ( iPorcentaje + 50 ) );
B := Round( B1 + ( B2 - B1 ) * 50 / ( iPorcentaje + 50 ) );
SL2[p].rgbtRed := R;
SL2[p].rgbtGreen := G;
SL2[p].rgbtBlue := B;
end;

if ( l > Imagen.Height - 2 ) then
m := 0
else
m := l + 1;

SL2 := Imagen.Picture.Bitmap.ScanLine[m];
R2 := SL2[p].rgbtRed;
G2 := SL2[p].rgbtGreen;
B2 := SL2[p].rgbtBlue;

if ( R1 <> R2 ) or ( G1 <> G2 ) or ( B1 <> B2 ) then
begin
R := Round( R1 + ( R2 - R1 ) * 50 / ( iPorcentaje + 50 ) );
G := Round( G1 + ( G2 - G1 ) * 50 / ( iPorcentaje + 50 ) );
B := Round( B1 + ( B2 - B1 ) * 50 / ( iPorcentaje + 50 ) );
SL2[p].rgbtRed := R;
SL2[p].rgbtGreen := G;
SL2[p].rgbtBlue := B;
end;
end;
end;
end;
end;

Suponiendo que tengamos en un formulario un objeto TImage llamado Image1 llamaríamos a este procedimiento de la siguiente manera:

Antialiasing( Image1, 10 );

Pruebas realizadas en Delphi 7.

Publicidad