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
| { ==================================================================== }
CONST
PixelCountMax = 65536;
Type
pRGBTripleArray = ^TRGBTripleArray;
TRGBTripleArray = ARRAY[0..PixelCountMax-1] of TRGBTriple;
{ ======================================================================= }
procedure TF_Princ.Btn_EmbossageClick(Sender: TObject);
Var
Bmp : TBitmap ;
begin
if (not Assigned(Image1.Picture.Graphic)) or (Image1.Picture.Graphic.Empty) then
Begin
Showmessage('Charger d''abord une image') ;
Exit ;
End ;
Bmp := TBitmap.Create ;
Bmp.Assign(Image1.Picture.Bitmap);
Embossage( Bmp );
Image1.Picture.Bitmap.Assign(Bmp);
Bmp.Free ;
end;
{ ================================================================== }
Procedure TF_Princ.Embossage( Var bmp1 : TBitmap ) ;
var
x2, y2 : integer; // Lignes et colonnes du bitmap - x1, y1 : Pixel à traiter par le filtre
x1, y1 : integer;
x0, y0 : integer;
scanrows0 : array[0..4000] of pRGBTripleArray ; // Image originale
row0 : PRGBTripleArray; // 3 lignes utilisées par le filtre
row1 : PRGBTripleArray;
row2 : PRGBTripleArray;
j, i : integer;
// R, G, B : integer;
VR , VG, VB : Integer ; // compoisante du pixel x1, y1
Imagebmp : TBitMap ;
Ascanrows0 : array[0..4000] of pRGBTripleArray; // Image transformée par le filtre
Arow1 : PRGBTripleArray; // Ligne du bitmap transformée
a : array[0..2, 0..2] of Real ; // coefficients du noyau du filtre
K : Real ; // pondération du filtre ( = 1 en general)
Somme : Real ; // Somme des termes du noyau du filtre
begin
if bmp1.height > 4000 then exit; // bitmap trop grand (à voir ?)
if bmp1.Width > 4000 then exit; // bitmap trop grand
K := 1 ; // Cas général sinon on peut forcer avec une valeur supérieure
a[0,0 ] := -2 * K ;
a[0,1 ] := -1 * K ;
a[0,2 ] := 0 * K ;
a[1,0 ] := -1 * K ;
a[1,1 ] := 0 * K ;
a[1,2 ] := 1 * K ;
a[2,0 ] := 0 * K ;
a[2,1 ] := 1 * K ;
a[2,2 ] := 2 * K ;
Somme := 0 ;
For i := 0 to 2 Do
For j := 0 To 2 Do
Somme := Somme + a[i, j] ;
Bmp1.PixelFormat := pf24bit ;
Imagebmp := Tbitmap.create;
Imagebmp.pixelformat := pf24bit;
ImageBmp.Width := Bmp1.Width;
ImageBmp.Height := Bmp1.Height;
ImageBmp.Assign(bmp1);
for y0 := 0 to ImageBMP.height-1 do Ascanrows0[y0] := ImageBmp.scanline[y0];
for y0 := 0 to Bmp1.height-1 do scanrows0[y0] := bmp1.scanline[y0];
// Traitement par le filtre
For y1 := 1 To bmp1.height-2 Do
Begin
y0 := y1 - 1 ;
Row0 := Scanrows0[y0];
Row1 := Scanrows0[y1];
ARow1 := AScanrows0[y1];
y2 := y1 + 1 ;
Row2 := Scanrows0[y2];
For x1 := 1 To bmp1.Width-2 Do
Begin
X0 := x1 -1 ;
x2 := X1 + 1 ;
VR := Round(Row0[x0].rgbtRed * a[0 , 0] +
Row0[x1].rgbtRed * a[0 , 1] +
Row0[x2].rgbtRed * a[0 , 2] +
Row1[x0].rgbtRed * a[1 , 0] +
Row1[x1].rgbtRed * a[1 , 1] +
Row1[x2].rgbtRed * a[1 , 2] +
Row2[x0].rgbtRed * a[2 , 0] +
Row2[x1].rgbtRed * a[2 , 1] +
Row2[x2].rgbtRed * a[2 , 2] ) ;
If Somme = 0 Then VR := VR + 128
Else VR := Round(VR / Somme) ;
If VR < 0 Then VR := 0 ;
If VR > 255 Then VR := 255 ;
ARow1[x1].rgbtRed := VR ;
VG := Round(Row0[x0].rgbtGreen * a[0 , 0] +
Row0[x1].rgbtGreen * a[0 , 1] +
Row0[x2].rgbtGreen * a[0 , 2] +
Row1[x0].rgbtGreen * a[1 , 0] +
Row1[x1].rgbtGreen * a[1 , 1] +
Row1[x2].rgbtGreen * a[1 , 2] +
Row2[x0].rgbtGreen * a[2 , 0] +
Row2[x1].rgbtGreen * a[2 , 1] +
Row2[x2].rgbtGreen * a[2 , 2]) ;
If Somme = 0 Then VG := VG + 128
Else VG := Round(VG / Somme) ;
If VG < 0 Then VG := 0 ;
If VG > 255 Then VG := 255 ;
ARow1[x1].rgbtGreen := VG ;
VB := Round(Row0[x0].rgbtBlue * a[0 , 0] +
Row0[x1].rgbtBlue * a[0 , 1] +
Row0[x2].rgbtBlue * a[0 , 2] +
Row1[x0].rgbtBlue * a[1 , 0] +
Row1[x1].rgbtBlue * a[1 , 1] +
Row1[x2].rgbtBlue * a[1 , 2] +
Row2[x0].rgbtBlue * a[2 , 0] +
Row2[x1].rgbtBlue * a[2 , 1] +
Row2[x2].rgbtBlue * a[2 , 2]) ;
If Somme = 0 Then VB := VB + 128
Else VB := Round(VB / Somme) ;
If VB < 0 Then VB := 0 ;
If VB > 255 Then VB := 255 ;
ARow1[x1].rgbtBlue := VB ;
End ;
End ;
// Recopie du bitmap transformé dans le bitmap original
Bmp1.Assign(ImageBMP);
ImageBmp.Free ;
end;
{ ========================================================================= } |
Partager