Bonjour, je suis confronté à un petit problème je n'arrive pas à voir et à saisir ou est mon erreur dans mes fonctions
Le but est d'appliquer à une image un flou circulaire ou radial
L'idée est simple pour le flou circulaire on transforme l'image en coordonnée polaire, on applique un flou de mouvement horizontal et on repasse l'image en coordonnée cartésienne
Pour le flou radial c'est la même chose sauf que l'on effectue un flou de mouvement vertical
Voila 2 captures d'écran
Le flou radial, celui-ci me semble correcte
Pièce jointe 527239
Le flou circulaire, il y a une cassure au milieu de l'image et cette effet de rotation que je ne veux pas naturellement
Pièce jointe 527242
Pièce jointe 527243
Voici mes fonctions en pascal de transformation polaire<-->cartesien
et de flou de mouvement :Code:
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 procedure TBZBitmapTransformations.CartesianToPolar; var x,y,dx,dy : Integer; dr, dt, r, theta, dtheta, SinAngle, CosAngle: Single; InColor : TBZColor; TmpBmp : TBZBitmap; begin dr := Sqrt(OwnerBitmap.CenterX * OwnerBitmap.CenterX + OwnerBitmap.CenterY * OwnerBitmap.CenterY) / OwnerBitmap.Height; dTheta := 360 / OwnerBitmap.Width; dt := DegToRadian(dTheta); r := dr; TmpBmp := TBZBitmap.Create(OwnerBitmap.Width, OwnerBitmap.Height); InColor := OwnerBitmap.GetPixel(OwnerBitmap.CenterX,OwnerBitmap.CenterY); for x := 0 to OwnerBitmap.MaxWidth do TmpBmp.setPixel(x,0, InColor); for y := 0 to OwnerBitmap.MaxHeight do begin theta := 0.0; for x := 0 to OwnerBitmap.MaxWidth do begin CosAngle := System.Cos(Theta); SinAngle := System.Sin(Theta); dx := round(OwnerBitmap.CenterX + r * CosAngle); dy := round(OwnerBitmap.CenterY + r * SinAngle); if OwnerBitmap.CheckPixelBound(dx, dy) then begin InColor := OwnerBitmap.getPixel(dx,dy) end else InColor := clrTransparent; TmpBmp.setPixel(x,y,InColor); Theta := Theta + dt; end; r := r + dr; end; OwnerBitmap.FastCopy(TmpBmp); FreeAndNil(TmpBmp); end; procedure TBZBitmapTransformations.PolarToCartesian; var ii,jj,Ind1, Ind2, m,n,x,y,px,py : Integer; weight, dr, dt, r, theta, dtheta, SinAngle, CosAngle, dx, dy : Single; AColor: TBZColor; xs,ys,ddx,ddy,cx,cy : Integer; TmpBmp : TBZBitmap; Const BiCubicRPrecal: Array[1..16] Of Single = (0.00260416666666667, 0.0208333333333333, 0.0703125, 0.166666666666667, 0.315104166666667, 0.479166666666667, 0.611979166666667, 0.666666666666667, 0.611979166666667, 0.479166666666667, 0.315104166666667, 0.166666666666667, 0.0703125, 0.0208333333333333, 0.00260416666666667, 0.0); begin dr := System.Sqrt(OwnerBitmap.CenterX * OwnerBitmap.CenterX + OwnerBitmap.CenterY * OwnerBitmap.CenterY) / OwnerBitmap.Height; dTheta := 360 / OwnerBitmap.Width; dt := DegToRadian(dTheta); r := dr; TmpBmp := TBZBitmap.Create(OwnerBitmap.Width, OwnerBitmap.Height); for y := 0 to OwnerBitmap.MaxHeight do begin theta := 0.0; for x := 0 to OwnerBitmap.MaxWidth do begin CosAngle := System.Cos(Theta); SinAngle := System.Sin(Theta); dx := (OwnerBitmap.CenterX + r * CosAngle); dy := (OwnerBitmap.CenterY + r * SinAngle); px := Round(dx); py := round(dy); if TmpBmp.CheckPixelBound(px, py) then begin AColor := OwnerBitmap.getPixel(x, y); xs := Ceil(dx - dt); ys := Ceil(dy - dr); cx := Floor(dx + dt); cy := Floor(dy + dr); ddx := cx - xs; ddy := cy - ys; For m := -1 To 2 Do Begin For n := -1 To 2 Do Begin Ind1 := round(4 * (m - ddx)) + 8; // Indice de correspondance avec la table précalculée Ind2 := round(4 * (n - ddy)) + 8; // Idem // Evite un bug d'indice hors limites Ind1 := Max(Min(Ind1, 16), 1); Ind2 := Max(Min(Ind2, 16), 1); weight := BiCubicRPrecal[ind1]*BiCubicRPrecal[ind2]; ii := Clamp((xs + m), 0, OwnerBitmap.MaxWidth); jj := Clamp((ys + n), 0, OwnerBitmap.MaxHeight); TmpBmp.setPixel(Floor(ii+m*weight),Floor(jj+n*weight),AColor); End; End; end; Theta := Theta + dt; end; r := r + dr; end; OwnerBitmap.FastCopy(TmpBmp); FreeAndNil(TmpBmp); end;
Pourriez vous m'aider à les corriger, pour solutionner le problème du flou circulaire. Il y a forcément quelque chose que je ne fais pas correctement, mais quoi ??? :weird:Code:
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 Procedure TBZBitmapBlurFilters.MotionBlur(direction, amount : Integer); //Type // TSumRec = packed record // Red,Green, Blue, Alpha : Single; // end; Var AColor, MColor: TBZColor; Dir: Single; x, y, xa, ya, maxh, maxw, m, s: Integer; incr: Integer; SinDir,CosDir,delta, DeltaC:single; mustdraw: Boolean; SumRec, FColor : TBZColorVector; //TSumRec; Begin s := Amount - 1; x:=0; y:=0; AColor := clrTransparent; MaxH := OwnerBitmap.MaxHeight + s; MaxW := OwnerBitmap.MaxWidth + s; Dir := DegToRad(direction); InitProgress(OwnerBitmap.Width,OwnerBitmap.Height); StartProgressSection(0,''); StartProgressSection(100,'Flou Motion'); Delta := 100 / MaxH + s; SinDir :=System.sin(dir); CosDir:=System.cos(dir); For Ya := -s To MaxH Do Begin For Xa := -s To MaxW Do Begin SumRec.Create(0,0); //With SumRec Do //Begin // Red := 0; // Green := 0; // Blue := 0; // Alpha := 0; //End; Incr := 0; mustdraw := False; For m := 1 To Amount Do Begin X := Xa + round(CosDir * m); Y := Ya + round(SinDir * m); If (X >= 0) And (X <= OwnerBitmap.MaxWidth) And (Y >= 0) And (Y <= OwnerBitmap.MaxHeight) Then Begin if (TBZBitmap(OwnerBitmap).UseMask) and (TBZBitmap(OwnerBitmap).Mask.Apply) then begin MColor := TBZBitmap(OwnerBitmap).Mask.GetPixel(X,Y); if MColor.Red>0 then begin FColor := OwnerBitmap.GetPixel(X, Y).AsColorVector; SumRec := SumRec + FColor; //With SumRec Do //Begin // Red := Red + AColor.Red; // Green := Green + AColor.Green; // Blue := Blue + AColor.Blue; // Alpha := Alpha + AColor.Alpha; //End; Inc(Incr); mustdraw := True; End; End else begin FColor := OwnerBitmap.GetPixel(X, Y).AsColorVector; SumRec := SumRec + FColor; //With SumRec Do //Begin // Red := Red + AColor.Red; // Green := Green + AColor.Green; // Blue := Blue + AColor.Blue; // Alpha := Alpha + AColor.Alpha; //End; Inc(Incr); mustdraw := True; End; End; End; If mustdraw Then Begin DeltaC := Incr.Reciprocal; SumRec := SumRec * DeltaC; //With AColor Do //Begin // Red := ClampByte(Round(SumRec.Red * deltaC)); // Green := ClampByte(Round(SumRec.Green * deltaC)); // Blue := ClampByte(Round(SumRec.Blue * deltaC)); // Alpha := ClampByte(Round(SumRec.Alpha * deltaC)); // /incr //End; AColor.Create(SumRec); OwnerBitmap.SetPixel(x, y, AColor); {%H-} End; End; AdvanceProgress(Delta, 0,1,True); End; FinishProgressSection(False); FinishProgressSection(True); End;
Merci d'avance
Jérôme