0/5 (3 avis)
Vue 6 889 fois - Téléchargée 470 fois
//Module : MOTEUR D'APPLICATION DE FILTRES GRAPHIQUES BASES SUR DES //MATRICES BIDIMENSIONNELLES 3x3 OU 5x5 DE PIXELS PONDERES PAR DES COEFFICIENTS. //Créé par MORLET Alexandre en Avril/Mai 2002 //Basé sur les travaux de Jean-Yves Quéinec //La fonction principale "Apply_Filter" reçoit en entrée les paramètres suivant : //1.Image Bitmap sur lequel agira le filtre //2.Filtre à appliquer sur le Bitmap //3.Rectangle de Sélection permettant d'appliquer le filtre sur une zone uniquement //Exemple de Filtres (la dernière valeur représente le Diviseur //[0,0,0,0,0, 0,1,2,1,0, 0,2,20,2,0, 0,1,2,1,0, 0,0,0,0,0], 32; Adoucir //[0,0,0,0,0, 0,-1,-2,-1,0, 0,-2,28,-2,0, 0,-1,-2,-1,0, 0,0,0,0,0], 16; Durcir //Trouvez vos propres filtres :-P UNIT U_ApplyFilter; INTERFACE USES Windows, Graphics; //L'API Windows fournit la structure TRGBtriple (3 bytes), qui décrit //les trois couleurs : .Rgbtred, .Rgbtgreen, .Rgbtblue dans un bitmap. //Tbitmap.pixelformat = pf24bit pour n'avoir qu'à traiter ce cas (en 16 millions de couleurs) //Un Filtre est caractérisé par une Matrice 5*5 ou 3*3 de coefficient ainsi qu'un Diviseur //Le Point Central de la Matrice est le pixel à traiter //En principe : Somme(coefficients de la Matrice) / Diviseur = 1 TYPE TRGB = RECORD R : integer; G : integer; B : integer; END; CONST //La Matrice de Référence permet de savoir si le Filtre utilisé //repose sur une Matrice 5x5 ou 3x3 MatrixModel : ARRAY[0..24] OF integer = (1,1,1,1,1, 1,0,0,0,1, 1,0,0,0,1, 1,0,0,0,1, 1,1,1,1,1); PROCEDURE APPLY_FILTER(VAR BMP : TBitmap; CONST Filter : ARRAY OF integer; CONST Diviseur : integer; CONST Rect : TRect); IMPLEMENTATION PROCEDURE APPLY_FILTER(VAR BMP : TBitmap; CONST Filter : ARRAY OF integer; CONST Diviseur : integer; CONST Rect : TRect); TYPE //Tableau de Triplet RGB (RGBTRed,RGBTGreen,RGBTBlue) où chaque composante est de type BYTE TRGBArray = ARRAY[0..0] OF TRGBTriple; //Pointeur vers un Tableau de Triplet PRGBArray = ^TRGBArray; VAR RGB : TRGB; New_RGB : TRGB; IM : integer; //Indice Matriciel pour l'indexage des coefficients mX, mY, dX, dY : integer; //Position de et dans la Matrice Glissante D : integer; //Décalage par rapport au centre de la Matrice cpt : integer; //Déclaration des tableaux de pointeur //Chaque pointeur pointe sur une ligne //Limitation dans le nombre de lignes à 2048 TabScanlineBMP : ARRAY OF PRGBArray; //Tableau Dynamique de Pointeurs sur Lignes TabScanlineFinalBMP : ARRAY OF PRGBArray; //Tableau Dynamique de Pointeurs sur Lignes //Position PosX et PosY dans l'image PosX, PosY : integer; //Image Bitmap avec Filtre FinalBMP : TBitmap; BEGIN //D=1 si Matrice 3x3 //D=2 si Matrice 5x5 D := 1; FOR cpt:=0 TO 24 DO IF ((Filter[cpt] AND MatrixModel[cpt]) <> 0) THEN BEGIN D := 2; Break; END; FinalBMP := TBitmap.Create; TRY FinalBMP.Assign(BMP); setLength(TabScanlineBMP, BMP.Height); setLength(TabScanlineFinalBMP, BMP.Height); //Stockage des Pointeurs de Scanlines FOR cpt := 0 TO BMP.Height-1 DO BEGIN TabScanlineBMP[cpt] := BMP.Scanline[cpt]; TabScanlineFinalBMP[cpt] := FinalBMP.Scanline[cpt]; END; FOR PosY := Rect.Top TO Rect.Bottom - 1 DO FOR PosX := Rect.Left TO Rect.Right - 1 DO BEGIN New_RGB.R :=0; New_RGB.G :=0; New_RGB.B :=0; //dX et dY pour le déplacement de la matrice glissante sur l'image FOR dY := -D TO D DO FOR dX := -D TO D DO BEGIN //iX et iY pour la position du pixel à traiter mY := PosY + dY; mX := PosX + dX; //Vérification des limites pour éviter les effets de bord //Lecture des composantes RGB de chaque pixel IF (mY >= 1) AND (mY <= BMP.Height - 1) AND (mX >= 1) AND (mX <= BMP.Width - 1) THEN BEGIN RGB.R := TabScanlineBMP[mY,mX].RGBTRed; RGB.G := TabScanlineBMP[mY,mX].RGBTGreen; RGB.B := TabScanlineBMP[mY,mX].RGBTBlue; END ELSE BEGIN RGB.R := TabScanlineBMP[PosY,PosX].RGBTRed; RGB.G := TabScanlineBMP[PosY,PosX].RGBTGreen; RGB.B := TabScanlineBMP[PosY,PosX].RGBTBlue; END; //Calcul de l'Indice Matriciel //Si dX et dY varie entre -2 et 2, Alors IM varie entre 0 et 24 IM := 12 + dY * 5 + dX; //Définition des nouvelles valeurs des composantes RGB en fonction du Filtre choisi New_RGB.R := New_RGB.R + RGB.R * Filter[IM]; //Multiplier par le Coefficient Matriciel New_RGB.G := New_RGB.G + RGB.G * Filter[IM]; New_RGB.B := New_RGB.B + RGB.B * Filter[IM]; END; New_RGB.R := New_RGB.R DIV Diviseur; New_RGB.G := New_RGB.G DIV Diviseur; New_RGB.B := New_RGB.B DIV Diviseur; //Vérification des limites sur le domaine de définition du type BYTE IF New_RGB.R > 255 THEN New_RGB.R := 255 ELSE IF New_RGB.R < 0 THEN New_RGB.R := 0; IF New_RGB.G > 255 THEN New_RGB.G := 255 ELSE IF New_RGB.G < 0 THEN New_RGB.G := 0; IF New_RGB.B > 255 THEN New_RGB.B := 255 ELSE IF New_RGB.B < 0 THEN New_RGB.B := 0; //Ecriture des nouvelles valeurs RGB dans l'image de destination TabScanlineFinalBMP[PosY,PosX].RGBTRed := New_RGB.R; TabScanlineFinalBMP[PosY,PosX].RGBTGreen := New_RGB.G; TabScanlineFinalBMP[PosY,PosX].RGBTBlue := New_RGB.B; END; BMP.Assign(FinalBMP); FINALLY FinalBMP.Free; END; END; END.
3 nov. 2004 à 12:51
merci d'avance
29 mai 2003 à 10:10
mais g essayé avec tes exemples et ca marche,
balaise,...
6 juil. 2002 à 19:11
G pas essayé mais ça a l'air cool mais vachement compliqué!
tu peux faire plus simple avec gdi ou setpixel() getpixel()
si tu vx t'inspirer, http://www.vbfrance.com/article.aspx?Val=4800
Vous n'êtes pas encore membre ?
inscrivez-vous, c'est gratuit et ça prend moins d'une minute !
Les membres obtiennent plus de réponses que les utilisateurs anonymes.
Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.
Le fait d'être membre vous permet d'avoir des options supplémentaires.