Les exemples de cet article résument les méthodes de traitement d’image de base de Delphi. Partagez-le avec tout le monde pour votre référence. L’analyse spécifique est la suivante :
//Procédure de gaufrage Emboss(SrcBmp,DestBmp:TBitmap;AzimuthChange:integer);overload;var i, j, Gray, Azimuthvalue, R, G, B: integer; = 0 à SrcBmp.Height - 1 commence SrcRGB := SrcBmp.ScanLine[i]; DestRGB := DestBmp.ScanLine[i]; si (AzimuthChange >= -180) et (AzimuthChange < -135) alors commencez si i > 0 alors SrcRGB1 := SrcBmp.ScanLine[i-1] sinon SrcRGB1 := SrcRGB; Inc(SrcRGB1); := SrcRGB; Inc(SrcRGB2); fin sinon si (AzimuthChange >= -135) et (AzimuthChange < -90) puis commence si i > 0 alors SrcRGB1 := SrcBmp.ScanLine[i-1] else SrcRGB1 := SrcRGB; SrcRGB2 := SrcRGB1; Inc(SrcRGB2); fin sinon si (AzimuthChange >= -90) et (AzimuthChange < -45) puis commencent si i > 0 alors SrcRGB1 := SrcBmp.ScanLine[i-1] else SrcRGB1 := SrcRGB2 := SrcRGB1 fin else if (AzimuthChange >= -45) et (AzimuthChange < 0) puis commencez SrcRGB1 := SrcRGB; si i > 0 alors SrcRGB2 := SrcBmp.ScanLine[i-1] else SrcRGB2 := SrcRGB; end else if (AzimuthChange >= 0) et (AzimuthChange < 45) alors commencez SrcRGB2 := SrcRGB; SrcBmp.Hauteur - 1) puis SrcRGB1 := SrcBmp.ScanLine[i+1] else SrcRGB1 := SrcRGB; fin sinon si (AzimuthChange >= 45) et (AzimuthChange < 90) puis commence si (i < SrcBmp.Height - 1) alors SrcRGB1 := SrcBmp.ScanLine[i +1] sinon SrcRGB1 := SrcRGB; SrcRGB1 ; fin sinon si (AzimuthChange >= 90) et (AzimuthChange < 135) puis commencer si (i < SrcBmp.Height - 1) then SrcRGB1 := SrcBmp.ScanLine[i+1] else SrcRGB1 := SrcRGB2 := SrcRGB1 ; Inc(SrcRGB1); fin sinon si (AzimuthChange >= 135) et (AzimuthChange <= 180) commencent alors if (i < SrcBmp.Height - 1) then SrcRGB2 := SrcBmp.ScanLine[i+1] else SrcRGB2 := SrcRGB Inc(SrcRGB2); = SrcRGB; Inc(SrcRGB1); fin pour j := 0 à SrcBmp.Width - 1 commence si (AzimuthChange >= -180) et (AzimuthChange < -135) puis commence Azimuthvalue := AzimuthChange + 180; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div 45)-((SrcRGB2.rgbtRed)*(45-Valeur d'azimut) div 45)+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Valeur d'azimut div 45)-((SrcRGB2.rgbtGreen)*(45- Valeur d'azimut)div 45)+78 ; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div 45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78; fin sinon si (AzimuthChange >= -135) et (AzimuthChange < -90) puis commencez la valeur d'azimut := Changement d'azimut + 135; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Valeur d'azimut div 45)-((SrcRGB2.rgbtRed)*(45-Valeur d'azimut) div 45)+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Valeur d'azimut div 45)-((SrcRGB2.rgbtGreen)*(45-Valeur d'azimut) div 45)+78; * Div de valeur d'azimut 45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78; fin sinon si (AzimuthChange >= -90) et (AzimuthChange < -45) alors commence si j=1 alors Inc(SrcRGB1,- 1); Valeur d'azimut := Changement d'azimut + 90 ; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Valeur d'azimut div 45)-((SrcRGB2.rgbtRed)*(45-Valeur d'azimut) div 45)+78; * Div de valeur d'azimut 45)-((SrcRGB2.rgbtGreen)*(45-Valeur d'azimut) div 45)+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Valeur d'azimut div 45)-((SrcRGB2.rgbtBlue)*(45- Valeur d'azimut) div 45)+78 ; fin sinon si (AzimuthChange >= -45) et (AzimuthChange < 0) alors commencez si j=1 alors commencez Inc(SrcRGB1,-1 Inc(SrcRGB2,-1) fin ; SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Valeur d'azimut div 45)-((SrcRGB2.rgbtRed)*(45-Valeur d'azimut) div 45)+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Valeur d'azimut div 45)-((SrcRGB2.rgbtGreen)*(45- Valeur d'azimut)div 45)+78 ; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Azimuthvalue div 45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78; fin sinon si (AzimuthChange >= 0) et (AzimuthChange < 45) alors commencez si j=1 alors commencez Inc(SrcRGB1,-1); Inc(SrcRGB2,-1); fin; Valeur d'azimut := Changement d'azimut; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Valeur d'azimut div 45)-((SrcRGB2.rgbtRed)*( 45-Valeur d'azimut)div 45)+78 ; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Valeur d'azimut div 45)-((SrcRGB2.rgbtGreen)*(45-Valeur d'azimut) div 45)+78; * Div de valeur d'azimut 45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78; fin sinon si (AzimuthChange >= 45) et (AzimuthChange < 90) alors commence si j=1 alors Inc(SrcRGB2,-1) ; Valeur d'azimut := Changement d'azimut - 45; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Valeur d'azimut div 45)-((SrcRGB2.rgbtRed)*(45-Valeur d'azimut) div 45)+78; * Div de valeur d'azimut 45)-((SrcRGB2.rgbtGreen)*(45-Valeur d'azimut) div 45)+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Valeur d'azimut div 45)-((SrcRGB2.rgbtBlue)*(45- Valeur d'azimut) div 45)+78 ; fin sinon si (AzimuthChange >= 90) et (AzimuthChange < 135) alors commencez Azimuthvalue := AzimuthChange - 90; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Azimuthvalue div 45)-((SrcRGB2.rgbtRed)*(45 -Valeur d'azimut) div 45)+78; G:=SrcRGB.rgbtGreen-((SrcRGB1.rgbtGreen)*Valeur d'azimut div 45)-((SrcRGB2.rgbtGreen)*(45-Valeur d'azimut) div 45)+78; (SrcRGB1.rgbtBlue)*Valeur d'azimut div 45)-((SrcRGB2.rgbtBlue)*(45-Azimuthvalue) div 45)+78; fin sinon si (AzimuthChange >= 135) et (AzimuthChange <= 180) puis commence Azimuthvalue := AzimuthChange - 135; R:=SrcRGB.rgbtRed-((SrcRGB1.rgbtRed)*Valeur d'azimut div 45)-((SrcRGB2.rgbtRed)*(45-Valeur d'azimut) div 45)+78; * Div de valeur d'azimut 45)-((SrcRGB2.rgbtGreen)*(45-Valeur d'azimut) div 45)+78; B:=SrcRGB.rgbtBlue-((SrcRGB1.rgbtBlue)*Valeur d'azimut div 45)-((SrcRGB2.rgbtBlue)*(45- Valeur d'azimut) div 45)+78 ; R : = Min (R, 255) ; R : = Max (R, 0) ; G : = Min (G, 255) ; B:=Max(B,0); Gris := (R shr 2) + (R shr 4) + (G shr 1) + (G shr 4) + (B shr 3) ; DestRGB.rgbtRed:=Gray; DestRGB.rgbtGreen:=Gray; DestRGB.rgbtBlue:=Gray; si (j=-180) et (AzimuthChange<-135)) ou ((AzimuthChange>=90) et (AzimuthChange<=180 ))) puis commencez Inc(SrcRGB1 end); (j=135) et (AzimuthChange<180)) ou ((AzimuthChange>=-180) et (AzimuthChange<=-90))) puis commencer Inc(SrcRGB2) ; fin;fin;fin;procédure Emboss(Bmp:TBitmap;AzimuthChange:integer;ElevationChange:integer;WeightChange:integer);surcharge;var DestBmp:TBitmap;begin DestBmp:=TBitmap.Create; Emboss(Bmp,DestBmp,AzimuthChange,ElevationChange; ,Changement de poids); Bmp.Assign(DestBmp);end;//Procédure inverse Negative(Bmp:TBitmap);var i, j: Integer; PRGB: pRGBTriple;begin Bmp.PixelFormat:=pf24Bit; pour i := 0 à Bmp.Height - 1 commencer PRGB := Bmp.ScanLine[i]; pour j := 0 à Bmp.Width - 1 faire début PRGB^.rgbtRed :=pas PRGB^.rgbtRed ; PRGB^.rgbtGreen :=pas PRGB^.rgbtBlue :=pas PRGB^.rgbtBlue Inc(PRGB);fin;// Procédure d'exposition Exposure(Bmp:TBitmap);var i, j: entier; PRGB: pRGBTriple;begin Bmp.PixelFormat:=pf24Bit; pour i := 0 à Bmp.Height - 1 commence PRGB := Bmp.ScanLine[i]; pour j := 0 à Bmp.Width - 1 commence si PRGB^.rgbtRed<128 alors PRGB^.rgbtRed :=pas PRGB^.rgbtRed ; si PRGB^.rgbtGreen<128 alors PRGB^.rgbtGreen :=pas PRGB^.rgbtGreen; si PRGB^.rgbtBlue<128 alors PRGB^.rgbtBlue :=pas PRGB^.rgbtBlue Inc(PRGB); SrcBmp:TBitmap);var i, j:Integer; SrcRGB:pRGBTriple; SrcNextRGB:pRGBTriple; SrcPreRGB:pRGBTriple; procédure IncRGB; début Inc(SrcNextRGB); SrcBmp.PixelFormat:=pf24Bit; pour i := 0 à SrcBmp.Height - 1 commence si i > 0 alors SrcPreRGB:=SrcBmp.ScanLine[i-1] sinon SrcPreRGB := SrcBmp.ScanLine[i]; SrcBmp.ScanLine[i]; si je < SrcBmp.Height - 1 then SrcNextRGB:=SrcBmp.ScanLine[i+1] else SrcNextRGB:=SrcBmp.ScanLine[i]; pour j := 0 à SrcBmp.Width - 1 commence si j > 0 alors DecRGB Value :=SrcPreRGB.rgbtRed+ SrcRGB ; .rgbtRed+SrcNextRGB.rgbtRed; si j > 0 puis IncRGB ; Valeur :=Valeur+SrcPreRGB.rgbtRed+SrcRGB.rgbtRed+SrcNextRGB.rgbtRed ; si j < SrcBmp.Width - 1, alors IncRGB ; Valeur :=(Valeur+SrcPreRGB.rgbtRed+SrcRGB.rgbtRed+SrcNextRGB.rgbtRed) division 9 ; DecRGB ; SrcRGB.rgbtRed :=valeur ; si j > 0, alors DecRGB ; Valeur :=SrcPreRGB.rgbtGreen+SrcRGB.rgbtGreen+SrcNextRGB.rgbtGreen ; Valeur :=Valeur+SrcPreRGB.rgbtGreen+SrcRGB.rgbtGreen+SrcNextRGB.rgbtGreen ; si j < SrcBmp.Width - 1 alors IncRGB ; Valeur :=(Valeur+SrcPreRGB.rgbtGreen+SrcRGB.rgbtGreen+SrcNextRGB.rgbtGreen) div 9 ; ; SrcRGB.rgbtGreen:=valeur ; si j>0 alors DecRGB ; Valeur :=SrcPreRGB.rgbtBlue+SrcRGB.rgbtBlue+SrcNextRGB.rgbtBlue ; si j>0 alors IncRGB ; .rgbtBlue; si j < SrcBmp.Width - 1 puis IncRGB; Value:=(Value+SrcPreRGB.rgbtBlue+SrcRGB.rgbtBlue+SrcNextRGB.rgbtBlue) div 9; SrcRGB.rgbtBlue:=value end;end;//procédure d'affûtage; Aiguiser(SrcBmp:TBitmap);var i, j: entier ; SrcRGB : pRGBTriple ; SrcPreRGB : pRGBTriple ; Valeur : entier ; début SrcBmp.PixelFormat : = pf24Bit ; SrcPreRGB:=SrcBmp.ScanLine[i-1] else SrcPreRGB:=SrcBmp.ScanLine[i]; pour j := 0 à SrcBmp.Width - 1 commence si j = 1 alors Dec(SrcPreRGB Value:=SrcRGB); rgbtRed+(SrcRGB.rgbtRed-SrcPreRGB.rgbtRed) div 2 ; Valeur :=Max(0,Valeur); Valeur :=Min(255,Valeur); SrcRGB.rgbtRed:=valeur :=SrcRGB.rgbtGreen-SrcPreRGB.rgbtGreen) div 2 ; Max(0,Valeur); Valeur :=Min(255,Valeur); SrcRGB.rgbtGreen:=valeur;=SrcRGB.rgbtBlue+(SrcRGB.rgbtBlue-SrcPreRGB.rgbtBlue) div 2; Valeur:=Max(0,Valeur); Valeur:=Min(255,Valeur); valeur Inc(SrcRGB); Inc(SrcPreRGB); fin; [Rotation et retournement de l'image] Le code suivant est implémenté à l'aide de ScanLine avec mouvement du pointeur, pour une couleur 24 bits ! //Procédure de rotation de 90 degrés Rotate90(const Bitmap:TBitmap);var i,j:Integer; rowIn,rowOut:pRGBTriple; Bitmap.Hauteur ; Bmp.Hauteur := Bitmap.Largeur ; Bmp.PixelFormat := pf24bit; Largeur:=Bitmap.Width-1; Hauteur:=Bitmap.Hauteur-1; pour j := 0 à Hauteur, commencez rowIn := Bitmap.ScanLine[j]; = Bmp.ScanLine[i]; Inc(rowOut,Hauteur - j); rowIn^ ; Bitmap.Assign(Bmp);end;//Procédure de rotation à 180 degrés Rotate180(const Bitmap:TBitmap);var i,j:Integer; rowIn,rowOut:pRGBTriple; TBitmap.Create; Bmp.Width := Bitmap.Width; Bitmap.Height; Bmp.PixelFormat := pf24bit; Largeur:=Bitmap.Width-1; Hauteur:=Bitmap.Height-1; pour j := 0 à la hauteur, commencez rowIn := Bitmap.ScanLine[j]; := 0 à Largeur commencer rowOut := Bmp.ScanLine[Height - j]; rowOut^ := rowIn^; pRGBTriple; Bmp:TBitmap; Largeur, Hauteur:Entier; début Bmp:=TBitmap.Create; := Bitmap.Height; Bmp.Height := Bitmap.Width; Bmp.PixelFormat := pf24bit; width:=Bitmap.Width-1; Height:=Bitmap.Height-1; := Bitmap.ScanLine[j]; pour i := 0 à Largeur, commencez rowOut := Bmp.ScanLine[Width - i]; Inc(rowOut,j); rowOut^ := rowIn^; Bitmap.Assign(Bmp);end;//Toute fonction d'angle RotateBitmap(Bitmap ); TBitmap;Angle:Integer;BackColor:TColor):TBitmap;var i,j,iOriginal,jOriginal,CosPoint,SinPoint: entier ; RowOriginal,RowRotated : pRGBTriple ; SinTheta,CosTheta : Extended ; AngleAdd : entier ; début Résultat : = TBitmap.Create ; Résultat.PixelFormat : = pf24bit ; ; si Angle<0 alors Angle:=360-Abs(Angle); si Angle=0 alors Result.Assign(Bitmap) sinon si Angle=90 alors commencez Result.Assign(Bitmap);//S'il est pivoté de 90 degrés, appelez directement Le code ci-dessus se termine sinon si (Angle>90) et (Angle<180) alors commence AngleAdd:=90; Angle:=Angle-AngleAdd; end else if Angle=180 then start Result.Assign(Bitmap);//S'il est pivoté de 180 degrés, appelez directement le processus ci-dessusend else if (Angle>180) et ( Angle<270) puis commencez AngleAdd:=180 ; Angle:=Angle-AngleAdd fin sinon si Angle=270 alors commencez ; Result.Assign(Bitmap); Rotate270(Result);//S'il est pivoté de 270 degrés, appelez directement la fin du processus ci-dessus sinon si (Angle>270) et (Angle<360) puis commencez AngleAdd:=270; Angle -AngleAdd; end else AngleAdd:=0; si (Angle>0) et (Angle<90) alors commencez SinCos((Angle + AngleAdd) * Pi / 180, SinTheta, CosTheta); si (SinTheta * CosTheta) < 0 alors commencez Result.Width := Round(Abs(Bitmap.Width * CosTheta - Bitmap.Height * SinTheta)); = Rond(Abs(Bitmap.Width * SinTheta - Bitmap.Height * CosTheta)); end else start Result.Width := Round(Abs(Bitmap.Width * CosTheta + Bitmap.Height * SinTheta)); Result.Height := Round(Abs(Bitmap.Width * SinTheta + Bitmap.Height * CosTheta)); ; CosTheta:=Abs(CosTheta); SinTheta:=Abs(SinTheta); (AngleAdd=0) ou (AngleAdd=180) puis commencez CosPoint:=Round(Bitmap.Height*CosTheta); SinPoint:=Round(Bitmap.Height*SinTheta); ); CosPoint:=Round(Bitmap.Width*SinTheta); fin pour j := 0 à Result.Height-1 commence RowRotated := Result.Scanline[j]; pour i := 0 à Result.Width-1 commence Case AngleAdd de 0 : commence jOriginal := Round((j+1)*CosTheta-( i+1-SinPoint)*SinTheta)-1; Round((i+1)*CosTheta-(CosPoint-j-1)*SinTheta)-1; fin; début iOriginal := Round((j+1)*SinTheta-(i+1-SinPoint)*CosTheta )-1; jOriginal := Bitmap.Hauteur-Round((i+1)*SinTheta-(CosPoint-j-1)*CosTheta); fin; 180 : début jOriginal := Bitmap.Height-Round((j+1)*CosTheta-(i+1-SinPoint)*SinTheta := Bitmap.Width-Round((i+1)*CosTheta-); (CosPoint-j-1)*SinTheta); fin ; 270 : début iOriginal := Bitmap.Width-Round((j+1)*SinTheta-(i+1-SinPoint)*CosTheta); jOriginal := Round((i+1)*SinTheta-(CosPoint-j-1)*CosTheta)-1 ; fin ; fin si (iOriginal >= 0) et (iOriginal <= Bitmap.Width-1) et (jOriginal >= 0) et (jOriginal <= Bitmap.Height-1) puis commencez RowOriginal := Bitmap.Scanline[jOriginal]; Inc(RowOriginal,iOriginal RowRotated^ := RowOriginal Inc(RowRotated); ; fin; fin; fin;//Procédure de retournement horizontal FlipHorz(const Bitmap:TBitmap);var i,j:Integer; rowIn,rowOut:pRGBTriple; Bmp:TBitmap; Largeur,Hauteur:Integer;begin Bmp:=TBitmap.Create; PixelFormat := pf24bit ; Largeur :=Bitmap.Width-1 ; Height:=Bitmap.Height-1; pour j := 0 à Height, commencez rowIn := Bitmap.ScanLine[j]; pour i := 0 à width, commencez rowOut := Bmp.ScanLine[j]; ,Width - i); rowOut^ := rowIn^; Inc(rowIn end); Bitmap.Assign(Bmp);end;//procédure de retournement vertical; FlipVert(const Bitmap:TBitmap);var i,j:Integer; rowIn,rowOut:pRGBTriple; Largeur, Hauteur:Integer;begin Bmp:=Bmp.Width := Bitmap.Height; Hauteur := Bitmap.Width; Bmp.PixelFormat := pf24bit; Largeur:=Bitmap.Width-1; Hauteur:=Bitmap.Hauteur-1; pour j := 0 à Hauteur, commencez rowIn := Bitmap.ScanLine[j]; pour i := 0 à Largeur, commencez rowOut := Bmp .ScanLine[Hauteur - j]; Inc(rowOut^ := rowIn^; fin; Bitmap.Assign(Bmp);end;[Réglage de la luminosité, du contraste et de la saturation] Le code suivant est implémenté à l'aide de ScanLine avec mouvement du pointeur ! fonction Min(a, b: entier): entier;commencer si a < b alors résultat := a sinon résultat := b;fin;fonction Max(a, b: entier): entier;commencer si a > b alors résultat : = a else résultat := b;end;//Procédure de réglage de la luminosité BrightnessChange(const SrcBmp,DestBmp:TBitmap;ValueChange:integer);var i, j: integer; SrcRGB, DestRGB : pRGBTriple ; commencer pour i := 0 à SrcBmp.Height - 1 commencer SrcRGB := SrcBmp.ScanLine[i]; DestRGB := DestBmp.ScanLine[i] pour j := 0 à SrcBmp.Width - 1 commencez si ValueChange > 0 puis commencez DestRGB.rgbtRed := Min(255, SrcRGB.rgbtRed + ValueChange); DestRGB.rgbtGreen := Min(255, SrcRGB.rgbtGreen + ValueChange); DestRGB.rgbtBlue := Min(255, SrcRGB.rgbtBlue + ValueChange); =Maximum(0, SrcRGB.rgbtRed + ValueChange); DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen + ValueChange); DestRGB.rgbtBlue := Max(0, SrcRGB.rgbtBlue + ValueChange Inc(SrcRGB); ; fin;fin;fin;//procédure de réglage du contraste ContrastChange(const SrcBmp,DestBmp:TBitmap;ValueChange:integer);var i, j: integer; SrcRGB, DestRGB: pRGBTriple;begin for i := 0 to SrcBmp.Height - 1 do start SrcRGB := SrcBmp.ScanLine[i] ; DestRGB := DestBmp.ScanLine[i]; := 0 à SrcBmp.Width - 1 commence si ValueChange>=0 puis commence si SrcRGB.rgbtRed >= 128 alors DestRGB.rgbtRed := Min(255, SrcRGB.rgbtRed + ValueChange) sinon DestRGB.rgbtRed := Max(0 , SrcRGB.rgbtRed - ValueChange); SrcRGB.rgbtGreen >= 128 puis DestRGB.rgbtGreen := Min(255, SrcRGB.rgbtGreen + ValueChange) sinon DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen - ValueChange) si SrcRGB.rgbtBlue >= 128 alors DestRGB.rgbtBlue); := Min(255, SrcRGB.rgbtBlue + ValueChange) else DestRGB.rgbtBlue := Max(0, SrcRGB.rgbtBlue - ValueChange); fin sinon commencer si SrcRGB.rgbtRed >= 128 alors DestRGB.rgbtRed := Max(128, SrcRGB.rgbtRed + ValueChange) sinon DestRGB.rgbtRed := Min(128, SrcRGB.rgbtRed - ValueChange); si SrcRGB.rgbtGreen >= 128 alors DestRGB.rgbtGreen := Max(128, SrcRGB.rgbtGreen + ValueChange) sinon DestRGB.rgbtGreen := Min(128, SrcRGB .rgbtVert - ValueChange); si SrcRGB.rgbtBlue >= 128 alors DestRGB.rgbtBlue := Max(128, SrcRGB.rgbtBlue + ValueChange) sinon DestRGB.rgbtBlue := Min(128, SrcRGB.rgbtBlue - ValueChange); Inc(DestRVB); fin ; end;end;//Procédure d'ajustement de la saturation SaturationChange(const SrcBmp,DestBmp:TBitmap;ValueChange:integer);var Grays: array[0..767] of Integer Alpha: array[0..255] of Word Gray , x, y : entier ; SrcRGB,DestRGB : pRGBTriple i ; Octet;beginValueChange:=ValueChange+255;for i := 0 à 255 do Alpha[i] := (i * ValueChange) Shr 8;x := 0;for i := 0 à 255 dobegin Gray := i - Alpha [i]; Gris[x] := Gris ; Gris[x] := Gris Inc(x] := Gris ; Inc(x);end; pour y := 0 à SrcBmp.Height - 1 dobegin SrcRGB := SrcBmp.ScanLine[Y]; DestBmp.ScanLine[Y] pour x := 0 à SrcBmp.Width - 1 commencez Gray := Grays[SrcRGB.rgbtRed + SrcRGB.rgbtGreen + SrcRGB.rgbtBlue]; si Gray + Alpha[SrcRGB.rgbtRed]>0 alors DestRGB.rgbtRed := Min(255,Gray + Alpha[SrcRGB.rgbtRed]) sinon DestRGB.rgbtRed := 0; rgbtGreen]>0 puis DestRGB.rgbtGreen := Min(255,Gray + Alpha[SrcRGB.rgbtGreen]) sinon DestRGB.rgbtGreen := 0; si Gray + Alpha[SrcRGB.rgbtBlue]>0 alors DestRGB.rgbtBlue := Min(255,Gray + Alpha[SrcRGB.rgbtBlue] ) sinon DestRGB.rgbtBlue := 0; Inc(DestRGB); end;end; end;//Procédure d'ajustement RVB RGBChange(SrcBmp,DestBmp:TBitmap;RedChange,GreenChange,BlueChange:integer);var SrcRGB, DestRGB: pRGBTriple; = 0 à SrcBmp.Height- 1 commence SrcRGB := SrcBmp.ScanLine[i]; DestRGB :=DestBmp.ScanLine[i]; pour j := 0 à SrcBmp.Width - 1 commence si RedChange> 0 alors DestRGB.rgbtRed := Min(255, SrcRGB.rgbtRed + RedChange) sinon DestRGB.rgbtRed := Max(0, SrcRGB.rgbtRed + RedChange); si GreenChange> 0 alors DestRGB.rgbtGreen := Min(255, SrcRGB.rgbtGreen + GreenChange) sinon DestRGB.rgbtGreen := Max(0, SrcRGB.rgbtGreen + GreenChange) ; .rgbtBlue := Min(255, SrcRGB.rgbtBlue + BlueChange) else DestRGB.rgbtBlue := Max(0, SrcRGB.rgbtBlue + BlueChange); Inc(SrcRGB); end; end;[Ajustement des couleurs]//RGB<=>BGRprocedure RGB2BGR(const Bitmap:TBitmap);var X : entier ; Y : entier PRGB ; pRGBTriple ; Couleur : Octet ; commence pour Y := 0 à (Bitmap.Height - 1) commence pour X := 0 à (Bitmap.Width - 1) commence Color := PRGB^.rgbtRed ; = PRGB^.rgbtBlue; PRGB^.rgbtBlue := Couleur Inc(PRGB fin); end;end;//Procédure en niveaux de gris (pondérée) Grayscale(const Bitmap:TBitmap);var X : Integer; Y : Integer; PRGB : pRGBTriple; Gray : Byte;begin for Y := 0 to (Bitmap.Height - 1) commencez PRGB := Bitmap.ScanLine[Y]; pour X := 0 à (Bitmap.Width - 1) commencez Gray := (77 * Rouge + 151 * Vert + 28 * Bleu) shr 8; PRGB^.rgbtRed:=Gris; PRGB^.rgbtGreen:=Gris; ;
Théorie:
Mots-clés :
Zone de dessin - c'est-à-dire la zone où la fenêtre affiche l'image, qui peut également être en plein écran (l'effet de dessin est meilleur en plein écran que dans la fenêtre générale)
Point central - c'est-à-dire les coordonnées du point central à afficher dans la zone de dessin de l'image originale (avertissement : ce concept est particulièrement important)
Parlons d'abord de l'agrandissement de l'image. Pour agrandir une image, notre approche générale consiste à agrandir directement l'image. Cependant, la méthode présentée dans cet article n'agrandit que la partie que nous pouvons voir. La première est celle de la zone. après l'agrandissement, c'est plus grand que la zone de dessin. Il n'y a rien à dire dans cette situation, bien sûr, tout est affiché. Image ; la seconde est que l'image agrandie est plus grande que la zone de dessin. C'est le sujet clé que nous allons aborder aujourd'hui. Dans ce cas, nous devons d'abord déterminer la taille de l'image agrandie, puis calculer la taille de l'image. image originale en fonction de la position et de la taille du « point central », et enfin agrandissez l'image capturée dans la zone de dessin.
Parlons de l'itinérance de l'image Lorsque l'image affichée dépasse la zone de dessin, nous devons parcourir l'image afin de voir l'image entière. Le principe est le suivant : lorsque la souris clique dans la zone de dessin, elle commence à se déplacer, enregistre d'abord la position du clic de la souris, puis détecte le mouvement de la souris, et calcule le « point central » en fonction de la souris et du dernier déplacement ( les coordonnées de l'écran doivent être converties en coordonnées de l'image originale), retirez la partie à afficher de l'image originale selon le principe de grossissement ci-dessus, puis agrandissez-la et affichez-la dans la zone de dessin.
Implémentation de l'algorithme :
1. Agrandissement de l'image
Définition des variables :
PZoom : taux de grossissement (entier : 100 % lorsque 100 est utilisé, 100 peut être modifié en 10 000 ou plus si nécessaire, mais les nombres à virgule flottante ne sont pas recommandés)
a, b : point central
w, h : largeur et hauteur de l'image originale à capturer
x, y : la position à intercepter (coin supérieur gauche)
sw,sh : largeur et hauteur de l'image originale
p1, p2 : rapport de grossissement
aw,ah : la taille de l'image agrandie
pw,ph : taille de la zone de dessin
vx,vy : la position affichée dans la zone de dessin (coin supérieur gauche)
vw, vh : la taille affichée dans la zone de dessin
ptx, pty : variables temporaires
Variables connues : PZoom, (a, b), (sw, sh), (p1, p2), (aw, ah), (pw, ph)
Variables à calculer : (x,y),(w,h),(vx,vy),(vw,vh)
Commencez à calculer :
aw=Round(PZoom*sw/100);ah=Round(PZoom*sh/100);p1=aw/pwp2=ah/ph// Remarque : Round est utilisé pour l'arrondi, comme Int(), Fix dans d'autres langues ()etc si p1>1 alors w=Round(sw/p1) sinon w=swif p2>1 alors h=Round(sh/p2) sinon h=sh// Remarque : shr est l'opérateur de décalage droit, vous pouvez utiliser ">>1", "div 2", "/2" ou "Round(w/2)" au lieu de x=aw shr 1y=bh shr 1 // Remarque : div est l'opérateur de division entière ptx=(w*PZoom) div 100pty=(h*PZoom) div 100// Ce qui suit calcule la taille et la position de l'image affichée dans la zone de dessin
variable
Pencent:double; // Taux de zoom wx:double; // Taux de zoom large hx:double; // Taux de zoom élevé wx:=pw/ptx hx:=ph/pty si wx>hx alors Pencent : =hx else Pencent:=wx; // Récupère la taille finale de l'image vw:=Round(Pencent*ptx); Calculer la position de l'image vx:=(pw-vw) div 2; vy:=(ph-vh) div 2;// -------------------- - ---------------
D'accord, deux tâches importantes ont été terminées (x, y), (w, h), (vx, vy), (vw, vh) ont été calculées. Le travail suivant est affiché. Nous choisissons l'API Windows pour effectuer l'opération.
variable
sDC est le handle de périphérique (DC) de l’image d’origine. tDC est le handle de périphérique temporaire dDC et le handle de périphérique final BitBlt(tDC,0,0,w,h,sDC,0,0,SRCCOPY);SetStretchBltMode(dDC. ,STRETCH_DELETESCANS);StretchBlt(dDC ,0,0,vw,vh,tDC,0,0,w,h,SRCCOPY);
Enfin, dessinez dans la zone affichée :
Par exemple:
BitBlt(GetDC(0),vx,vy,vx+vw,xy+vh,dDC,0,0,SRCCOPY);
2. Itinérance des images
Définissez d’abord trois variables globales :
FBeginDragPoint :TPoint; // Enregistre la position où la souris commence à glisser FBeginDragSBPoint :TPoint; // Enregistre la position du "point central" FBeginDrag :boolean; // Si le "glisser" a, b a commencé : integer; " Emplacement
Lorsque vous cliquez sur le bouton gauche de la souris, enregistrez la position de la souris et la position du "point central", et définissez FBeginDrag sur true.
Lorsque le bouton droit de la souris apparaît, définissez FBeginDrag sur false
Lorsque la souris bouge, FBeginDrag est jugé. Si c'est faux, aucun traitement ne sera effectué. Si c'est vrai, le traitement suivant sera effectué.
Supposons que X et Y soient la position actuelle de la souris
a=FBeginDragPoint.X-((X-FBeginDragPoint.X)*100) div PZoomb=FBeginDragPoint.Y-((Y-FBeginDragPoint.Y)*100) div PZoom
Enfin, utilisez l'image présentée ci-dessus pour agrandir et afficher l'image
Conseils:
1. Si l'image est volumineuse, une erreur de dépassement de mémoire se produira lors de l'utilisation de l'objet bitmap de Delphi. Dans ce cas, vous pouvez définir les paramètres suivants :
bitImage:=TBitmap.Create; bitImage.PixelFormat:=pf24bit;
2. Si vous souhaitez que l'image s'adapte automatiquement à la taille de la fenêtre, référez-vous au code suivant :
var p1,p2 :double;begin p1:=pw/sw; p2:=ph/sw; si p1>p2 alors PZoom:=Round(p2*100) sinon PZoom:=Round(p1*100); 0 puis PZoom:=100;fin;
Traitement de la luminosité des couleurs des pixels de l'image en niveaux de gris Delphi
Dans le traitement d’images, la vitesse est importante. Par conséquent, nous devons retraiter TBitmap pour obtenir TVczhBitmap. C'est simplement parce que GetPixels et SetPixels sont trop lents, utilisez simplement une autre méthode.
unité untBitmapProc ; l'interface utilise Graphics, SysUtils ; tapez TVczhBitmap=class(TBitmap) private Data:PByteArray; Line:Integer; function GetBytePointer(X,Y:Integer):PByte; :Byte); fonction GetBytes(X,Y:Integer):Byte; constructeur publié protégé Create; propriété publique Bytes[X,Y:Integer]:Byte read GetBytes write SetBytes; procédure LoadFromFile(FileName:String); procédure d'implémentation TVczhBitmap.SetFormat; début HandleType:=bmDIB; TVczhBitmap.GetBytePointer(X,Y:Integer):PByte commence si Line<>Y alors début Ligne:=Y; Données:=ScanLine[Y]; fin; Longint(result):=Longint(Data)+X; procédure TVczhBitmap.SetBytes(X,Y:Integer;Value:Byte); X,Y)^:=Valeur fin ; fonction TVczhBitmap.GetBytes(X,Y:Integer):Byte start; result:=GetBytePointer(X,Y)^; fin; constructeur TVczhBitmap.Create; début hérité SetFormat; fin; procédure TVczhBitmap.LoadFromFile(FileName:String); ; Ligne :=-1 ; procédure TVczhBitmap.ToGray ; var X,Y,R :Integer ; B:Octet ; commencer pour Y :=0 à Hauteur-1 faire pour X :=0 à Largeur-1 faire commencer R:=0 ; pour B :=0 à 2 faire R:=R+GetBytes(X*3+ B,Y); pour B:=0 à 2, faites SetBytes(X*3+B,Y,R div end;
Après cela, nous devons créer plusieurs formulaires. Le premier est utilisé pour afficher des images et le second est utilisé pour traiter les images. Tous les autres formulaires héritent du second formulaire et contiennent les méthodes de traitement réelles.
Regardons d'abord la deuxième fenêtre :
unité untProc ; l'interface utilise Windows, Messages, SysUtils, Variants, Classes, Graphiques, Contrôles, Formulaires, Boîtes de dialogue, ExtCtrls, untBitmapProc, StdCtrls, ComCtrls ; tapez TfrmProcessor = class(TForm) pbBar : TPaintBox ; procédure FormCreate(Expéditeur : TObject); procédure FormDestroy (Expéditeur: TObject); procédure FormShow (Expéditeur: TObject); procédure pbBarPaint (Expéditeur: TObject); procédure Button1Click (Expéditeur: TObject); private { Déclarations privées } public { Déclarations publiques } BarData:array[0 ..255]de Byte ; TVczhBitmap ; fin de la procédure DrawBar ; l'implémentation {$R *.dfm} utilise untViewer ; procédure Bar.Canvas.MoveTo(0,255-BarData[0]); I:=1 à 255 faire Bar.Canvas.LineTo(I,255-BarData[I]); TfrmProcessor.FormCreate(Expéditeur : TObject); commencer Bar:=TVczhBitmap.Create; Bar.Width:=256; Bar.Height:=256; =bsSolid ; fin ; procédure TfrmProcessor.FormDestroy (Expéditeur : TObject ; commencer Bar.Free ); fin; procédure TfrmProcessor.FormShow(Sender: TObject); var I:Integer; start for I:=0 to 255 do BarData[I]:=I; end; .Canvas.Draw(0,0,Fin de la barre); procédure TfrmProcessor.Button1Click(Expéditeur : TObject); var X,Y:Integer ; commencer pour Y:=0 à Buffer.Height-1 faire pour X:=0 à Buffer.Width*3-1 faire Played.Bytes[X,Y]:=BarData[Buffer.Bytes[ X,Y]]; frmViewer.FormPaint(frmViewer fin);
Après cela, créez une fenêtre qui en hérite, puis ajustez BarData[] et appuyez sur Appliquer pour voir le résultat.
Commencez maintenant à traiter l'image. Voir l'exemple de programme pour des effets spécifiques.
1. Inversion des couleurs.
Les couleurs des images en niveaux de gris vont de 0 à 255, donc pour inverser la couleur, nous pouvons soustraire la valeur de couleur de 255 pour obtenir la couleur inversée.
var I:Integer; start hérité; pour I:=0 à 255 do BarData[I]:=255-I;//Soustraire la valeur de couleur de 255 DrawBar(pbBar end);
2. Réduisez la gamme de couleurs pour améliorer ou affaiblir la luminosité
La couleur est initialement comprise entre 0 et 255. Si vous ajustez sa plage, par exemple de 0 à 16, l'image sera nettement plus sombre. Nous pouvons définir la valeur de départ sur a et la valeur de fin sur b, puis la nouvelle valeur de couleur New=a+(b-1)*Old/255. Cela modifie la luminosité sans détruire la séquence de couleurs d'origine. Le code est le suivant
var I:Integer; début pour I:=0 à 255 do BarData[I]:=(255-sbMin.Position)+Round((sbMin.Position-sbMax.Position)/255*I); ); Bouton1Clic(Bouton1);
Les sbMin.Position et sbMaxPosition ici sont tous deux inversés. Par conséquent, utilisez 255 pour soustraire
3. Augmentez la gamme de couleurs dans une certaine plage
Si l'image elle-même présente une petite gamme de couleurs, vous pouvez utiliser cette méthode pour augmenter le contraste de l'image, ce qui est bénéfique pour l'analyse de l'image. Méthodes spécifiques :
Sélectionnez une valeur a comme valeur de départ, sélectionnez une valeur b comme valeur de fin, puis déformez selon la formule suivante :
| 0 (X<=une)
f(X)= | 255/(ba)*(Xa)
| 255(X>=b)
var I:Integer; commencer pour I:=0 à 255 commencer si I<=sbMin.Position alors BarData[I]:=0 sinon si I>=sbMax.Position alors BarData[I]:=255 sinon BarData[I ]:=Round(255/(sbMax.Position-sbMin.Position)*(I-sbMin.Position)); end; pbBarPaint(pbBar); Bouton1Clic(Bouton1);
4. Convertir en images en noir et blanc
Lorsque vous utilisez la troisième fonction, vous constaterez que lorsque b<=a, les couleurs de l'image sont blanches sauf le noir. Les bénéfices de cette opération ne peuvent pas être directement affichés. Cela ne sera efficace que lorsqu’il s’agira d’un traitement d’image plus avancé tel que la détection des contours. Cet exemple peut être transformé à l’aide de la formule de la troisième méthode, il ne sera donc pas développé en détail.
5. Réglage exponentiel de la luminosité
Nous supposons que le domaine de ce graphique est [0,1] et que la plage de valeurs est également [0,1]. Ensuite, définissez la fonction f(x)=x^c, puis l'image de f(x) a une section comme indiqué ci-dessus. Lorsque nous utilisons la souris pour fonctionner à nouveau, nous pouvons prendre un point P (a, b) dessus, puis faire passer f (x) à travers le point p, puis c = ln (b) / ln (a). Avec C, nous pouvons fonctionner sur la couleur:
Nouveau = (ancien / 255) ^ c * 255 = exp (ln (old / 255) * c) * 255 var ea, eb, ec: étendu; / 255; ec: = ln (eb) / ln (ea); Bardata [i]: Round (exp (ln (i / 255)) * ec) * 255);
Cela ajuste la luminosité de l'image.
Conseils pour afficher des effets spéciaux dans les graphiques de Delphi
Aperçu
---- à l'heure actuelle, dans de nombreux CD de logiciels et de jeux d'apprentissage, vous pouvez souvent voir divers
La technologie de l'affichage graphique repose sur le mouvement, l'entragation, la forme de goutte de pluie, les stores, l'empilement de blocs de construction et d'autres méthodes d'affichage des graphiques pour rendre l'image plus vivante et plus attrayante pour le public. Cet article explorera comment implémenter diverses techniques d'affichage graphique à Delphi.
Principes de base
---- Dans Delphi, il est très simple d'afficher une image. et le fichier sélectionné sera affiché dans le composant Timage. Mais cela affiche simplement les graphiques directement sous la forme, et il n'y a aucune compétence. Afin de faire en sorte que l'affichage graphique ait un effet unique, vous pouvez suivre les étapes suivantes:
---- Définissez un composant Timage et chargez d'abord les graphiques à afficher dans le composant Timage, c'est-à-dire charger le contenu graphique du disque dans la mémoire en cache graphique.
---- Créez un nouvel objet bitmap avec la même taille que les graphiques dans le composant Timage.
---- Utilisez la fonction du droit d'auteur de la toile (copiez la zone rectangulaire d'une toile dans la zone rectangulaire d'une autre toile), utilisez des techniques et forme dynamiquement
Convertissez le contenu du fichier en un bitmap, puis affichez le bitmap dans le formulaire.
---- Méthode d'implémentation
Diverses techniques d'affichage graphique sont introduites ci-dessous:
1. Effet de la pression
Tirez les graphiques à afficher dans l'écran à partir des directions vers le haut, vers le bas, la gauche et la droite, et en même temps couvrer les anciens graphiques d'origine à l'écran. Tirez à gauche et tirez à droite. mais les principes sont similaires, prenant l'effet de traction comme exemple.
Principe: Tout d'abord, déplacez la première ligne horizontale dans le graphique temporaire vers le dernier dans le bitmap à afficher, puis déplacez les deux premières lignes horizontales du graphique temporaire vers les deux derniers bitmaps à afficher. Déplacez les trois et quatre premières lignes jusqu'à ce que toutes les données graphiques soient déplacées. Pendant le processus mobile, vous pouvez voir que le bitmap affiché flotte de bas en haut, réalisant un effet de traction.
Algorithme de programme:
Procédure tform1.button1click (expéditeur: tobject); : = image1.height; BMPWidth: = Image1.Width; i: = 0 à bmpheight do Newbmp.Canvas.Copyrect (RECT (0, bmpheight-i, bmpwidth, bmpheight), image1.canvas, rect (0,0, bmpwidth, i)); , newbmp); fin; newbmp.free;
2. Effet vertical échelonné
Principe: divisez les graphiques à afficher en deux parties. Depuis l'écran, vous pouvez voir que les graphiques plus légers apparaissant aux extrémités supérieures et inférieures se déplacent vers le centre de l'écran jusqu'à ce qu'ils soient complètement clairs.
Algorithme de programme:
Procédure tform1.button4click (expéditeur: tobject); ; bmpheight: = image1.Height; I: = 0; bmpheight-i + j-1, bmpwidth, bmpheight-i + j)); (0, bmpheight-j, bmpwidth, bmpheight-j + 1), image1.canvas, rect (0, ij, bmpwidth, i-j + 1)); (120,100, newbmp); i: = i + 2;
3. Effet décalé horizontal
Principe: le même principe que l'effet d'interlimentation verticale, sauf que les graphiques divisés en deux groupes sont déplacés respectivement dans l'écran des extrémités gauche et droite.
Algorithme de programme:
Procédure tform1.button5click (expéditeur: tobject); ; bmpheight: = image1.Height; i: = 0; tandis que i <= bmpwidth commence I + J-1,0, bmpwidth-i + j, bmpheight)); (bmpwidth-j, 0, bmpwidth-j + 1, bmpheight), image1.canvas, rect (ij, 0, i-j + 1, bmpheight); j: = j-2; (120,100, newbmp); i: = i + 2;
4. Effet de goutte de pluie
Principe: déplacez la dernière ligne de balayage des graphiques temporaires vers le premier vers la dernière ligne de balayage du bitmap visible en séquence, permettant à cette ligne de balayage de laisser sa trace sur l'écran. Ensuite, l'avant-dernière ligne de balayage des graphiques temporaires est déplacé vers le premier à l'avant-dernière lignes de balayage du bitmap visible en séquence. Et ainsi de suite pour les lignes de balayage restantes.
Algorithme de programme:
Procédure tform1.Button3Click (Sender: TOBject); ; bmpheight: = image1.Height; pour i: = bmpheight downto 1 do for j: = 1 to je commence newbmp.canvas.copyrect (rect (0, j-1, bmpwidth, j), image1.canvas, rect (0, i-1, bmpwidth, i));
5. ENTRE EFFET
Principe: Divisez les données placées dans les graphiques temporaires en plusieurs groupes, puis les déplacer séquentiellement du premier groupe au dernier groupe. Time Déplacez la deuxième ligne de balayage, puis déplacez les troisième et quatrième lignes de scan.
Algorithme de programme:
Procédure tform1.button6click (expéditeur: tobject); hauteur: = image1.height; bmpheight: = image1.height; bmpwidth: = image1.width; -1, bmpwidth, xcount * j + i), image1.canvas, RECT (0, XCount * J + I-1, BMPWidth, XCount * J + I);
6. Effet du bloc de construction
Principe: Il s'agit d'une variation de l'effet de goutte de pluie.
Algorithme de programme:
Procédure TForm1.Button7Click (Sender: TOBject); ; bmpheight: = image1.Height; i: = bmpheight; tandis que i> 0 commence pour j: = 10 à je commence newbmp.canvas.copyrect (rect (0, j-10, bmpwidth, j), image1.canvas, rect (0, i-10 , bmpwidth, i)); fin;
Conclusion
Les effets d'affichage graphique ci-dessus ont tous été transmis sur la machine. Cela fonctionne très bien.
Implémentation d'image Magnificateur à l'aide de Delphi
Ajoutez deux composants Timage au formulaire. Un autre composant Timage a sa propriété de nom définie sur Image2, qui affiche l'image agrandie.
Le noyau de cet exemple est la fonction Stretchblt.
Procédure tform1.image1mousmove (expéditeur: tobject; shif 20,40,40, SRCCOPY); Screen.Cursors [1]: = LoadCursorFromFile ('Magnify.cur');
Le programme appellera d'abord la fonction StretchBlt, utilise la position actuelle de la souris comme point central, sélectionnez l'image partielle sur le composant Image1 avec une longueur latérale de 40 et agrandissez l'image partielle dans le composant Image2. Actualisez ensuite l'affichage du composant Image2 en appelant la méthode de rafraîchissement du composant Image2. Enfin, définissez le pointeur de la souris sur la nouvelle forme.
Le code du programme est le suivant :
Unité Unité 1; InterfaceUSEwindows, Messages, Sysutils, Variants, Classes, Graphiques, Contrôles, Formulaires, Dialogue, Extctrls, Stdctrls; Type TFORM1 = Classe (TForm) Image1: TIMAGE; ; FormMousMove (expéditeur: tobject; shift: tshiftState;; shift: tshiftState; x, y: entier); BeginStRetchBlt (image2.Canvas.Handle, 0,0, image2.width, image2.Height, image1.canvas.handle, x-20, y-20,40,40, srccopy); ]: = LoadCursorFromFile ('MAGNIFY.CUR'); Self.cursor: = 1; end; procédure tform1.formMouseMove (expéditeur: tobject; shift: tshiftState; x, y: entier); begin screen.cursors [1]: = crdefault; .
Enregistrez le fichier, puis appuyez sur la touche F9 pour exécuter le programme et le programme s'exécutera.
Les images agrandies sont une fonction essentielle d'un excellent logiciel de visualisation d'images.
J'espère que cet article sera utile à la programmation Delphi de chacun.