Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Multimedia (https://www.delphipraxis.net/16-multimedia/)
-   -   Delphi Hilfe bei Farbverlauf procedure (https://www.delphipraxis.net/138698-hilfe-bei-farbverlauf-procedure.html)

Blamaster 15. Aug 2009 15:31


Hilfe bei Farbverlauf procedure
 
Hi,

ich habe eine Farbverlauf Procedure erstellt, die verläufe zwischen belibig vielen Farben erstellen kann.

Delphi-Quellcode:
procedure DrawGradient(Bmp: TBitmap; TColorArray: array of TColor);
var
  Diff_R, Diff_G, Diff_B: integer;
  R_Value, G_Value, B_Value: byte;
  Steps, y, x: integer;
begin
  Steps := 255;
  Bmp.Width := Steps * high(TColorArray);

  for x := 0 to (high(TColorArray) -1) do
  begin
    R_Value := GetRValue(TColorArray[x]);
    G_Value := GetGValue(TColorArray[x]);
    B_Value := GetBValue(TColorArray[x]);

    Diff_R := round((GetRValue(TColorArray[x + 1]) - GetRValue(TColorArray[x])) / Steps);
    Diff_G := round((GetGValue(TColorArray[x + 1]) - GetGValue(TColorArray[x])) / Steps);
    Diff_B := round((GetBValue(TColorArray[x + 1]) - GetBValue(TColorArray[x])) / Steps);

    for y := x * Steps to Steps * (x + 1) do
    begin
      R_Value := R_Value + Diff_R;
      G_Value := G_Value + Diff_G;
      B_Value := B_Value + Diff_B;

      Bmp.Canvas.Pen.Color := RGB(R_Value, G_Value, B_Value);
      Bmp.Canvas.MoveTo(y, 0);
      Bmp.Canvas.LineTo(y, Bmp.Height);
    end;
  end;

end;
Zwischen einigen Farben geht das auch problemlos.

Beispiel Blau -> Rot:

http://img31.imageshack.us/i/richtigc.jpg/

Zwischen manchen kommt es aber zu fehlern Grün -> Blau

http://img232.imageshack.us/i/falsch.jpg/

Jemand eine Idee woran das liegen kann ?

mfg Yannic

Muetze1 15. Aug 2009 17:32

Re: Hilfe bei Farbverlauf procedure
 
Kleine Frage zum Nachdenken: Was ist, wenn die Differenz zwischen den Rotanteilen der Quell- und Zielfarbe recht klein ist, bzw. mindestens kleiner als deine Schrittanzahl? Dann wird es ein 0,xxx Wert den du leider mit Round zu einer Ganzzahl wegrationalisierst und somit kommt da unter Umständen mit 1 oder sogar 0 viel zu viel bzw. viel zu wenig pro Schritt raus. Du solltest also mal darüber nachdenken deine Differenzvariablen als Fließkomma auszulegen...

sx2008 15. Aug 2009 20:00

Re: Hilfe bei Farbverlauf procedure
 
Ausserdem vermischt du zwei Aufgaben in einer Funktion:
a.) Farbverlauf berechnen
b.) Farbverlauf zeichen

Beide Aufgaben sollten strikt voneinander getrennt werden.

Du hast ja mehrere "Stützfarben" in deinem ColorArray.
Angenommen, es sind 5 Farben und der Farbverlauf geht von 0% bis 100%.
Dann gilt:
0% -> ColorArray[0]
25% -> ColorArray[1]
50% -> ColorArray[2]
75% -> ColorArray[3]
100% -> ColorArray[4]

Welche Farbe wäre dann bei 10% ?
Irgendeine Mischung zwischen ColorArray[0] und ColorArray[1].
Letztendlich brauchst du immer eine Mischfarbe zwischen zwei Farben.
Und wäre es nicht günstig, dafür eine extra Funktion zu haben?

Ich hoffe das bringt dich jetzt auf den richtigen Weg.

Blamaster 16. Aug 2009 12:47

Re: Hilfe bei Farbverlauf procedure
 
Oh mist, daran hatte ich ja garnicht gedacht :wall:

Jetzt funktioniert es wie es soll.

Aber eins kann ich nicht ganz nachvollziehen. Und zwar wo genau der Vorteil liegt hier das berechnen und zeichnen zu trennen. Ich sehe da bis jetzt keinen vorteil sondern eher Nachteile.

mfg Yannic

sx2008 16. Aug 2009 17:46

Re: Hilfe bei Farbverlauf procedure
 
Zitat:

Zitat von Blamaster
Und zwar wo genau der Vorteil liegt hier das berechnen und zeichnen zu trennen. Ich sehe da bis jetzt keinen vorteil sondern eher Nachteile.

Es gibt doch ganz verschiedene Farbverläufe - horizontal, vertikal, im 45 Grad Winkel, als Kreis oder Torte, dreieckig,...
Wäre doch ungeschickt, wenn man für jede Art zu zeichnen die Berechnung neu erfinden müsste.
Ausserdem kann man durch die Trennung den Farbverlauf cachen (in einem Array of TColor);
also einmal berechnen und immer wieder benützen, bis sich die Stützfarben oder die Anzahl der Farben ändert.

Blamaster 16. Aug 2009 18:31

Re: Hilfe bei Farbverlauf procedure
 
Hi,

stimmt hast recht ist doch praktischer die Daten in einem Array vorliegen zu haben.

mfg Yannic

mimi 31. Aug 2009 11:07

Re: Hilfe bei Farbverlauf procedure
 
Zitat:

Es gibt doch ganz verschiedene Farbverläufe - horizontal, vertikal, im 45 Grad Winkel, als Kreis oder Torte, dreieckig,...
Wäre doch ungeschickt, wenn man für jede Art zu zeichnen die Berechnung neu erfinden müsste.
Musst du das nicht sowieso ? Angenommen ich möchte ein neuen Farbverlauf Typ einfügen, dann ist es doch erforderlich das eine ganz andere Rechnung da hinter steht.
Je nach Art des Farbverlaufs.....

Das Zeichnen bräuchte man nur einmal. Das Stimmt. Wenn der Array immer die gleichen Daten enthält.

Blup 31. Aug 2009 12:00

Re: Hilfe bei Farbverlauf procedure
 
Es gibt nur einen Typ von linearem Farbverlauf, mehrdimensionale Verläufe lassen sich auf eindimensionale Verläufe zurückführen.
Falls eine progressive oder andere Kurve durch das Farbspektrum gewünscht wird, braucht man natürlich eine neue Funktion zur Erstellung. Die Funktionen zum Zeichnen müssen aber dazu nicht geändert werden.

Medium 31. Aug 2009 12:04

Re: Hilfe bei Farbverlauf procedure
 
Nö, so ein Array von Farben kann dann als LUT benutzt werden. Will ich z.B. nen diagonalen Verlauf haben:
Farbe[X, Y] = Array[(X*Y+Y) div High(Array)]

Will ich nen radialen:
Farbe[X, Y] = Array[(Dist(center, Point(X, Y))*High(Array)) div MaxDist]

usw.

Für alles das selbe Array als Basis verwendet, also ist es mehr als sinnvoll das so zu separieren.

Kalfany 31. Aug 2009 13:14

Re: Hilfe bei Farbverlauf procedure
 
Liste der Anhänge anzeigen (Anzahl: 2)
Folgendes Bsp. zeichnet einen Verlauf von links nach rechts.

Delphi-Quellcode:
procedure Gradient(Canvas: TCanvas; Width,Height: Integer; BeginColor,EndColor: TColor);
var
  RGBValue: array[0..2] of Byte;
  RGBDiff: array[0..2] of Integer;
  Rect:    TRect;
  i:       Integer;
  R, G, B: Byte;
begin
  RGBValue[0] := GetRValue(ColorToRGB(BeginColor));
  RGBValue[1] := GetGValue(ColorToRGB(BeginColor));
  RGBValue[2] := GetBValue(ColorToRGB(BeginColor));
  RGBDiff[0] := GetRValue(ColorToRGB(EndColor)) - RGBValue[0];
  RGBDiff[1] := GetGValue(ColorToRGB(EndColor)) - RGBValue[1];
  RGBDiff[2] := GetBValue(ColorToRGB(EndColor)) - RGBValue[2];

  Canvas.Pen.Style := psSolid;
  Canvas.Pen.Mode := pmCopy;
  Rect.Top   := 0;
  Rect.Bottom := Height;

  for i := 0 to 255 do
  begin
     Rect.Left := MulDiv(i, Width, 255);
     Rect.Right := MulDiv(i + 1, Width, 255);

     R := RGBValue[0] + MulDiv(i, RGBDiff[0], 255 - 1);
     G := RGBValue[1] + MulDiv(i, RGBDiff[1], 255 - 1);
     B := RGBValue[2] + MulDiv(i, RGBDiff[2], 255 - 1);

     Canvas.Brush.Color := RGB(R, G, B);
     Canvas.FillRect(Rect);
  end;
end;

mimi 31. Aug 2009 14:27

Re: Hilfe bei Farbverlauf procedure
 
ich habe mal eine Klasse gebastelt dort habe ich Fertige Farbverläufe rein kopiert. Verschiedene. Allerdings war jeder Farbverlauf anders...

Medium 31. Aug 2009 14:30

Re: Hilfe bei Farbverlauf procedure
 
@Kalfany: Herzlichen Glückwunsch! Sie haben 95% des Threads entweder nicht gelesen, oder nicht verstanden! :party:

Kalfany 31. Aug 2009 16:04

Re: Hilfe bei Farbverlauf procedure
 
Zitat:

Zitat von Medium
@Kalfany: Herzlichen Glückwunsch! Sie haben 95% des Threads entweder nicht gelesen, oder nicht verstanden! :party:

Sagen wirs so ... ich hab von den 5% die ich gelesen hab 95% nicht verstanden :mrgreen: (Ich schieb das ganze jetzt mal auf meine akt. Medikamente :roteyes: :tongue: ) Aber evtl. kann jemand anders das Bsp. ja mal brauchen.

mimi 31. Aug 2009 16:09

Re: Hilfe bei Farbverlauf procedure
 
Deine Funktion ist ja ganz nett, aber dort kann ich ja nur zwei Farben angeben, aber es ging darum glaube ich mehrere Farben in einem Array anzugeben. Außerdem hast du das Zeichnen und das Berechnen nicht voneinander getrennt.

Medium 31. Aug 2009 16:45

Re: Hilfe bei Farbverlauf procedure
 
Zitat:

Zitat von Kalfany
meine akt. Medikamente :roteyes: :tongue:

Scheint ne gut Kombi zu sein! Evtl. wäre die Zusammenstellung mal was für unsere Code-Lib :stupid:

DeddyH 31. Aug 2009 16:50

Re: Hilfe bei Farbverlauf procedure
 
[OT]
Zitat:

Zitat von german-bash
Neun von zehn Stimmen in meinen Kopf sagen ich bin nicht verrückt.
Die andere summt die Melodie von Tetris...

:mrgreen: [/OT]

Maik81ftl 31. Mär 2011 11:34

AW: Hilfe bei Farbverlauf procedure
 
Moin Moin,

Darf ich Dieses Thema einmal für meinen Farbverlauf aufgreifen, da es schon dieses angeht.

Bei mir, steht das Problem jedoch etwas anders.

Ich habe eine Grundfarbe (z.B. clred oder clLime).

der Aktuelle stand ist wie folgt.
  • procedure ColorToHLS(const AColor: TColor; out H, L, S: Byte);
  • procedure RGBtoHLS(const R, G, B: Byte; out H, L, S: Byte);
  • function HLStoColor(const H, L, S: Byte): TColor;
  • procedure HLStoRGB(const H, L, S: Byte; out R, G, B: Byte);

Dank dieser habe ich die die werte beommen, welche ich nun nur noch sinnvoll auswerten muß.
  • {Rot
  • // $9191FF; H:0; L:200; S:255 | R:137; G:128; B:255
  • // $4D4DFF; H:0; L:166; S:255 | R:143; G:128; B:255
  • // clRed; H:0; L:128; S:255 | R:149; G:128; B:255 <--- Grundfarbe
  • // $0000B3; H:0; L: 90; S:255 | R:155; G:128; B:255
  • // $000066; H:0; L: 51; S:255 | R:162; G:128; B:255}
  • {Lime
  • // $99FF99; H: 85; L:204; S:255 | R:140; G:170; B:255
  • // $4DFF4D; H: 85; L:166; S:255 | R:150; G:170; B:255
  • // clLime; H: 85; L:128; S:255 | R:160; G:170; B:255 <--- Grundfarbe
  • // $00B300; H: 85; L: 90; S:255 | R:169; G:170; B:255
  • // $006600; H: 85; L: 51; S:255 | R:177; G:153; B:255}

Generelle Idee bei mir ist, das ich einen "Grundwert" habe, und von da an 2 werte mir je einer Stufe heller und 2 Werte mit je einer Stufe Dunkler zurückerhalte.

Analog steht da auch schon ein thema in diesem Forum Farbverlauf bei Canvas. Bitte nicht wundern, Urspünglich wollte ich dies auf einem TLabel anwenden.

Kleine aber Wichtige Info zusätzlich an Rande:

Ich Programmiere mir Lazarus auf einem Ubuntu 64bit system.

Bin für jede Hilfe dankbar.

shmia 31. Mär 2011 17:47

AW: Hilfe bei Farbverlauf procedure
 
Zitat:

Zitat von Maik81ftl (Beitrag 1092206)
Generelle Idee bei mir ist, das ich einen "Grundwert" habe, und von da an 2 werte mir je einer Stufe heller und 2 Werte mit je einer Stufe Dunkler zurückerhalte.

Dann hast du also insgesamt 5 Farben.
Diese Farben müssen im RGB-Farbsystem vorliegen.
Mit den folgenden Funktionen aus der Code-Library: Farbverlauf berechnen
ist es dann ein Leichtes einen Farbverlauf zu erzeugen, der diese 5 Farben benützt.

Maik81ftl 31. Mär 2011 18:38

AW: Hilfe bei Farbverlauf procedure
 
Zitat:

Zitat von shmia (Beitrag 1092259)
Zitat:

Zitat von Maik81ftl (Beitrag 1092206)
Generelle Idee bei mir ist, das ich einen "Grundwert" habe, und von da an 2 werte mir je einer Stufe heller und 2 Werte mit je einer Stufe Dunkler zurückerhalte.

Dann hast du also insgesamt 5 Farben.
Diese Farben müssen im RGB-Farbsystem vorliegen.
Mit den folgenden Funktionen aus der Code-Library: Farbverlauf berechnen
ist es dann ein Leichtes einen Farbverlauf zu erzeugen, der diese 5 Farben benützt.

der gedanke kam mir auch schon und danke für die Link aber da Stört mich eine kleine sache.

function ColorBetween(C1, C2 : TColor; blend:Real):TColor; da muß ich mind, 2 werte eingeben. bei dem Ausgang steht allerdings nur ein Wert zur verfühgung. :(

und wie auch zuerkennen ist liegen die Farben im RGB und HLS vor. Aber wird mir schon was einfallen...

Blup 1. Apr 2011 09:04

AW: Hilfe bei Farbverlauf procedure
 
Zitat:

Zitat von Maik81ftl (Beitrag 1092276)
function ColorBetween(C1, C2 : TColor; blend:Real):TColor; da muß ich mind, 2 werte eingeben. bei dem Ausgang steht allerdings nur ein Wert zur verfühgung. :(

Eventuell könnte man diese Funktion in einer Schleife aufrufen, dabei ändert sich "blend" abhängig von der Position zwischen den beiden Farben.

Zitat:

Zitat von Maik81ftl (Beitrag 1092276)
und wie auch zuerkennen ist liegen die Farben im RGB und HLS vor. Aber wird mir schon was einfallen...

Wie auch zu erkennen ist, sind dir die Funktionen zur Umwandlung zwischen den Farbräumen schon aufgefallen...

shmia 1. Apr 2011 10:40

AW: Hilfe bei Farbverlauf procedure
 
Zitat:

Zitat von Maik81ftl (Beitrag 1092276)
function ColorBetween(C1, C2 : TColor; blend:Real):TColor; da muß ich mind, 2 werte eingeben. bei dem Ausgang steht allerdings nur ein Wert zur verfühgung.

Dann schau nochmal genauer hin; die überladene Funktion gibt es in einer Variante, die beliebig viele Farben entgegen nimmt.
Wenn du 5 Farben übergibst, dann bekommst du den Verlauf in sagen wir mal 101 Schritten so:
Delphi-Quellcode:
for i:=0 to 100 do
begin
  blend := i * 0.01; // blend bewegt sich zwischen 0.0 bis 1.0 !!
  farbe := ColorsBetween([clBlack, clRed, clYellow, clWhite, clGreen], blend);
  // hier mit farbe etwas tun....
end;
Anstelle von clBlack, clRed,... übergibst du natürlich deine eigenen 5 Farben.

Maik81ftl 1. Apr 2011 11:20

AW: Hilfe bei Farbverlauf procedure
 
Delphi-Quellcode:
function Farbverlauf(bValue: Boolean; cValue: TColor):TProgSet;
Var H, S: Byte;
    L: Array[0..4] of Byte;
    Col: TProgSet;
begin
  if bValue then
    begin
    ColorToHLS(cValue, H, L[2], S);
    Col.Menst[4]:= HLStoColor(H, L[2]-38-38, S);
    Col.Menst[3]:= HLStoColor(H, L[2]  -38, S);
    Col.Menst[2]:= cValue;
    Col.Menst[1]:= HLStoColor(H, L[2]  +38, S);
    Col.Menst[0]:= HLStoColor(H, L[2]+38+38, S);
    Col.Periode:= Form3.Progset.Periode;
    end;
  if not bValue then
    begin
    ColorToHLS(cValue, H, L[2], S);
    Col.Periode[4]:= HLStoColor(H, L[2]-38-38, S);
    Col.Periode[3]:= HLStoColor(H, L[2]  -38, S);
    Col.Periode[2]:= cValue;
    Col.Periode[1]:= HLStoColor(H, L[2]  +38, S);
    Col.Periode[0]:= HLStoColor(H, L[2]+38+38, S);
    Col.Menst:= Form3.Progset.Menst;
    end;
  Result:= Col;
end;
Was haltet Ihr denne von der Variante???

shmia 1. Apr 2011 15:12

AW: Hilfe bei Farbverlauf procedure
 
Liste der Anhänge anzeigen (Anzahl: 1)
Also irgendwie ist für dich ein Farbverlauf etwas anderes als für mich.
Meine Definition von Farbverlauf:
Ein Farbverlauf ermöglicht stufenloses Überblenden von 2 Farben.
Der Überblendungsfaktor bewegt sich dabei zwischen 0.0 (=0%) bis 1.0 (=100%).
Einen Farbverlauf zwischen mehreren Farben erreicht man dadurch, dass man hintereinander mehrere Farben überblendet.
Für dein Vorhaben brauchst du eigentlich nur 2 Randfarben:
2 stufen dunkler und 2 stufen heller als die Grundfarbe.
Genau in der Mitte also bei 50% liegt dann deine Grundfarbe im Verlauf.

Kleines Demo im Anhang.

Maik81ftl 1. Apr 2011 16:10

AW: Hilfe bei Farbverlauf procedure
 
Zitat:

Zitat von shmia (Beitrag 1092444)
Also irgendwie ist für dich ein Farbverlauf etwas anderes als für mich.
Meine Definition von Farbverlauf:
Ein Farbverlauf ermöglicht stufenloses Überblenden von 2 Farben.
Der Überblendungsfaktor bewegt sich dabei zwischen 0.0 (=0%) bis 1.0 (=100%).
Einen Farbverlauf zwischen mehreren Farben erreicht man dadurch, dass man hintereinander mehrere Farben überblendet.
Für dein Vorhaben brauchst du eigentlich nur 2 Randfarben:
2 stufen dunkler und 2 stufen heller als die Grundfarbe.
Genau in der Mitte also bei 50% liegt dann deine Grundfarbe im Verlauf.

Kleines Demo im Anhang.

Korektur. wie du es auch dem code entnehemn kannst recht ir das mit einer Farbe aus. und ja, bei mir ist es mehr eine Farbstufung als ein verlauf.


Alle Zeitangaben in WEZ +1. Es ist jetzt 10:04 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz