Delphi-PRAXiS
Seite 1 von 3  1 23      

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;


Alle Zeitangaben in WEZ +1. Es ist jetzt 04:11 Uhr.
Seite 1 von 3  1 23      

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