Ist wesentlich komplizierter, als es sich im Titel anhört.
Ich schreibe an einem Programm, was u.a. ermöglichen soll, bei Bildern die "Sättigung" und die "Farbe" zu ändern. Sättigung klappt, Problem ist die Änderung der Farbe, ohne dabei die phys. Helligkeit und die Sättigung der Farbe zu ändern.
Ich orientiere mich im wesentlichen an den Erläuterungen hier:
home.arcor.de/ulile/node52.html
Eine Änderung der Farbe eines Pixels entspricht also einer Drehung des Pixels um die Raumdiagonale (0,0,0 / 255,255,255) im RGB-Würfel. Ich weiss aus der Schule, wie ich einen Punkt um eine der Koordiantenachsen (hier heissen die nicht x,y,z, sondern r,g,b).
Ich kann die Raumdiagonale so drehen, dass sie auf eine der Achsen (z.B. R) fällt. Wenn ich den so mitgedrehten Pixel dann um Winkel Alpha um die R-Achse drehe, und anschliessend die vorigen Drehungen rückgängig mache (um den entsprechenden Winkel zurückdrehen), dann habe ich (nach meiner Überlegung) eine Drehung um die Diagonale um Alpha berechnet.
Folgenden Quelltext habe ich, wobei die Trackbar von 0 bis 360 geht
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:
| const cos45:real = 0.707106781186548; sin45:real = 0.707106781186548; cos35:real = 0.816496580927726; sin35:real = 0.577350269189625;
[...] var OriginalBild:Tbitmap; Editbild:Tbitmap; [...] procedure TForm1.TrackbarFChange(Sender: TObject); var x,y:integer; P,EditP : PByteArray; alpha:real; rt1,gt1,bt1:real; rt2,gt2,bt2:real; rint,bint,gint:integer; begin alpha:=TrackbarF.Position/180 *Pi; for y := 0 to EditBild.Height -1 do begin P := OriginalBild.ScanLine[y]; EditP := EditBild.ScanLine[y]; for x := 0 to EditBild.Width -1 do begin bt1:=P[3*x]/255; gt1:=P[3*x+1]/255; rt1:=P[3*x+2]/255;
bt2 := cos45*bt1 - sin45*rt1; gt2 := gt1; rt2 := sin45*bt1 + cos45*rt1;
bt1 := bt2; gt1 := cos35*gt2 + sin35*rt2; rt1 := -sin35*gt2 + cos35*rt2;
bt2 := cos(alpha)*bt1 - sin(alpha)*gt1; gt2 := sin(alpha)*bt1 + cos(alpha)*gt1; rt2 := rt1;
bt1 := bt2; gt1 := cos35*gt2 - sin35*rt2; rt1 := sin35*gt2 + cos35*rt2;
bt2 := cos45*bt1 + sin45*rt1; gt2 := gt1; rt2 := -sin45*bt1 + cos45*rt1;
bint:=round(bt2*255); gint:=round(gt2*255); rint:=round(rt2*255); if bint>255 then bint:=255; if gint>255 then gint:=255; if rint>255 then rint:=255; if bint<0 then bint:=0; if gint<0 then gint:=0; if rint<0 then rint:=0; EditP[3*x] := bint; EditP[3*x+1] := gint; EditP[3*x+2] := rint; end; end; image1.Canvas.Draw(0,0,EditBild); end; |
In etwa funktioniert das auch. Allerdings beobachte ich bei einem Graustufenbild (Grauwerte liegen genau auf der Raumdiagonalen) AUCH eine Veränderung der Farbwerte, wenn ich die Trackbar verschiebe. Das kann aber eigentlich nicht sein, oder? Sieht jemand den Fehler? Oder hat Anregungen, woran das liegen könnte? Bin über alles dankbar. Vielleicht kann ein mathematisch versierter auch mal meine Winkel kontrollieren, ich hab da z.Z. einen ganzen Bretterstapel vorm Kopf...
We are, we were and will not be.