Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   farbverlauf in % (https://www.delphipraxis.net/128480-farbverlauf.html)

lbccaleb 30. Jan 2009 14:34


farbverlauf in %
 
Hallo,

hab da mal wieder ein kleines Problem ;-(

Wie ist es möglich ein Farbwert zu erzeugen (Grün, Gelb, Rot)?

Ich habe dabei 0-100% zur verfügung!

Also, bei 0 % soll es Rot sein, und bei 100% Grün!
Gibt es dafür schon Code um das zu berechnen??

Dankeschonmal..

shmia 30. Jan 2009 14:37

Re: farbverlauf in %
 
Code-Library: Farbverlauf berechnen

lbccaleb 30. Jan 2009 14:43

Re: farbverlauf in %
 
Ok, hab vergessen zu erwähnen, alles nonVCl!! ;-(

shmia 30. Jan 2009 14:47

Re: farbverlauf in %
 
Zitat:

Zitat von lbccaleb
... alles nonVCl!! ;-(

Das Brechnen eines Farbverlauf IST nonVCL.
Erst beim 2. Schritt; also das Zeichnen der Farbe auf einem Fenster gibt es Unterschiede zwischen VCL und nonVCL.

himitsu 30. Jan 2009 14:52

Re: farbverlauf in %
 
Mathematik?

z.B.:
Delphi-Quellcode:
Farbe := (Trunc(255 / 100 * Prozent) * (clRed and $fefefe))
  or (Trunc(255 / 100 * (100 - Prozent) * (clLime and $fefefe));

Farbe := (255 * Prozent div 100 * (clRed and $fefefe))
  or (255 * (100 - Prozent) div 100 * (clLime and $fefefe));

lbccaleb 30. Jan 2009 15:17

Re: farbverlauf in %
 
Für diese funktion muss ich die Unit "Graphics" einbinden! Das will ich nicht ;-(

Naja ich hatte an RGB(.., .., ..) gedacht!

Sowas in der Form:
Delphi-Quellcode:
function MakeColor(prozent: integer): COLORREF;
  begin;

   
    result := RGB(..);
  end;
Nur leider weiß ich nicht so richtig wie ich das berechnen soll, das ich je nach Prozent einen gleitenden übergang von Rot zu Grün hinnbekomme..

shmia 30. Jan 2009 15:43

Re: farbverlauf in %
 
Zitat:

Zitat von lbccaleb
Für diese funktion muss ich die Unit "Graphics" einbinden! Das will ich nicht ;-(

Die einzigste Funktion, die aus Unit Graphics benötigt wird, ist diese:
Delphi-Quellcode:
type
  PColor = ^TColor;
  TColor = -$7FFFFFFF-1..$7FFFFFFF;
...
function ColorToRGB(Color: TColor): Longint;
begin
  if Color < 0 then
    Result := GetSysColor(Color and $000000FF) else
    Result := Color;
end;
Copy & Paste dürfte hier ja erlaubt sein.
Die anderen Funktionen (RGB() und GetRValue,...) sind aus Unit Windows und gegen diese Unit hast du wohl nichts.

himitsu 30. Jan 2009 15:46

Re: farbverlauf in %
 
Dann übernimm einfach nur den Wert der dieser Farbkonastanten,
oder trag die Berechnungen in die RGB-Funktion ein?
Delphi-Quellcode:
Farbe := {red}(255 * Prozent div 100)
  or (255 * (100 - Prozent) div 100 * $0100);

Farbe := RGB(255 * Prozent div 100, 255 * (100 - Prozent) div 100, 0);

lbccaleb 30. Jan 2009 20:23

Re: farbverlauf in %
 
Ok, danke werde es morgen nochmal versuchen..

lbccaleb 31. Jan 2009 14:21

Re: farbverlauf in %
 
Habe das jetzt mal ausprobiert, aber irgendwie ist das noch nciht das was ich suche...

das Problem ist ja, das ich nicht alle Farben auf die selbe Art berechnen kann, ich will ja nur nen Übergang hinnbekommen von Rot zu Gelb zu Grün!

Wenn ich es so mache, dann hab ich ja auch andere Farben dazwischen, ;-(
Ich hab immer noch keine Idee wie ich das berechne :gruebel:

Garfield 31. Jan 2009 16:49

Re: farbverlauf in %
 
Dann sieh Dir dies mal an: http://efg2.com/Lab/Graphics/Colors/MaxwellTriangle.htm

himitsu 31. Jan 2009 20:59

Re: farbverlauf in %
 
wenn du unbedingt über 3 Farben gehen willst, dann mußt du die Berechnung teilen
0%-50% Farbe1 > Farbe2
50-100% Farbe2 > Farbe2

aber Rot + Grün ergibt doch Gelb.
also sollte der Farbverlauf von Rot nach Grün auch über Gelb gehen?
(es sei denn ich hab mich verrechnet)

OK, 50% Rot + 50% Grün = 50% Gelb = dunkelgelb


Delphi-Quellcode:
Farbe = RGB(255 * Min(Prozent, 50) div 50, 255 * Min(100 - Prozent, 50) div 50, 0);
Delphi-Quellcode:
// eine Form mit Memo1:TMemo und Image1:TImage (.Stretch=true)

Procedure TForm1.FormCreate(Sender: TObject);
  Var Prozent: Integer;

  Begin
    Image1.Picture.Bitmap.Width := 101;
    Image1.Picture.Bitmap.Height := 8;

    // jede Farbe gleichmäßig über den gesamten Bereich verteilt
    For Prozent := 0 to 100 do Begin
      Memo1.Lines.Add(Format('%d    R:%d G:%d    F1:$%.8x  F2:$%.8x', [Prozent,
        {red}255 * Prozent div 100,
        {grün}255 * (100 - Prozent) div 100,
        {red}(255 * Prozent div 100) or {grün}(255 * (100 - Prozent) div 100 * $0100),
        RGB(255 * Prozent div 100, 255 * (100 - Prozent) div 100, 0)]));
      Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 0] :=
        RGB(255 * Prozent div 100, 255 * (100 - Prozent) div 100, 0);
    End;

    Memo1.Lines.Add('');

    // jede Farbe nur über den halben Bereich verteilt
    For Prozent := 0 to 100 do
      If Prozent <= 50 Then Begin
        Memo1.Lines.Add(Format('%d  R:%d G:%d  F1:$%.8x F2:$%.8x', [Prozent,
          {red}255 * Prozent div 50,
          {grün}255,
          {red}(255 * Prozent div 50) or {grün}(255 * $0100),
          RGB(255 * Prozent div 50, 255, 0)]));
        Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 3] :=
          RGB(255 * Prozent div 50, 255, 0);
      End Else Begin
        Memo1.Lines.Add(Format('%d  R:%d G:%d  F1:$%.8x F2:$%.8x', [Prozent,
          {red}255,
          {grün}255 * (100 - Prozent) div 50,
          {red}(255) or {grün}(255 * (100 - Prozent) div 50 * $0100),
          RGB(255, 255 * (100 - Prozent) div 50, 0)]));
        Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 3] :=
          RGB(255, 255 * (100 - Prozent) div 50, 0);
      End;

    Memo1.Lines.Add('');

    // jede Farbe nur über den halben Bereich verteilt - zusammengefaßt
    For Prozent := 0 to 100 do Begin
      Memo1.Lines.Add(Format('%d  R:%d G:%d  F1:$%.8x F2:$%.8x', [Prozent,
        {red}255 * Min(Prozent, 50) div 50,
        {grün}255 * Min(100 - Prozent, 50) div 50,
        {red}(255 * Min(Prozent, 50) div 50) or {grün}(255 * Min(100 - Prozent, 50) div 50 * $0100),
        RGB(255 * Min(Prozent, 50) div 50, 255 * Min(100 - Prozent, 50) div 50, 0)]));
      Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 6] :=
        RGB(255 * Min(Prozent, 50) div 50, 255 * Min(100 - Prozent, 50) div 50, 0);
    End;

    For Prozent := 0 to 100 do Begin
      Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 1] := Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 0];
      Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 2] := Self.Color;
      Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 4] := Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 3];
      Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 5] := Self.Color;
      Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 7] := Image1.Picture.Bitmap.Canvas.Pixels[Prozent, 6];
    End;
  End;

(*
object Form1: TForm1
  Left = 0
  Top = 0
  Caption = 'Form1'
  ClientHeight = 505
  ClientWidth = 337
  OnCreate = FormCreate
  object Image1: TImage
    Left = 8
    Top = 424
    Width = 321
    Height = 73
    Anchors = [akRight, akBottom]
    Stretch = True
  end
  object Memo1: TMemo
    Left = 8
    Top = 8
    Width = 321
    Height = 410
    Anchors = [akLeft, akTop, akRight, akBottom]
    ScrollBars = ssBoth
  end
end
*)
aber wie gesagt, alles nur ein bissl Mathematik ... hätt man sich auch selbst ausrechen können, bzw. selbst die passenden Formeln erstellen können

lbccaleb 31. Jan 2009 22:37

Re: farbverlauf in %
 
Liste der Anhänge anzeigen (Anzahl: 1)
Joa danke, genau das wars was ich brauchte...
Danke..

Umgewandelt noch in eine Funktion (Math in Uses aufnehmen):

Delphi-Quellcode:
function GetColor(Prozent: integer): COLORREF;
  begin
    Result := RGB(255 * Min(100 - Prozent, 50) div 50, 255 * Min(Prozent, 50) div 50, 0);
  end;

mr_emre_d 31. Jan 2009 23:41

Re: farbverlauf in %
 
Delphi-Quellcode:
function Gradient( ACanvas: TCanvas;
  Pos: TRect; const FromColor, ToColor: Cardinal ): Boolean;
var
  x: Integer;
  NewColor: Cardinal;
  Percent: Single;
  rOP, gOP, bOP: Single; // One Percent
begin
  Result := False;
  {Initialization}
  Pos.Right := Pos.Right - Pos.Left; // Right = Width
  Pos.Bottom := Pos.Bottom - Pos.Top; // Bottom = Height
  with ACanvas do
  begin
    rOP := (GetRValue(ToColor)-GetRValue(FromColor)) / Pos.Right;
    gOP := (GetGValue(ToColor)-GetGValue(FromColor)) / Pos.Right;
    bOP := (GetBValue(ToColor)-GetBValue(FromColor)) / Pos.Right;
    for x := 1 to Pos.Right do
    begin
      NewColor := RGB( GetRValue(FromColor)+Round(rOP*x),
        GetGValue(FromColor)+Round(gOP*x),
        GetBValue(FromColor)+Round(bOP*x) );
      Pen.Color := NewColor;
      MoveTo( Pos.Left+x, Pos.Top );
      LineTo( Pos.Left+x, Pos.Top+Pos.Bottom );
    end;
  end;
  Result := not Result;
end;

himitsu 1. Feb 2009 00:15

Re: farbverlauf in %
 
@mr_emre_d: Zieh verfehlt, es sei denn du hast noch soeinene Funktion mit 3 Parametern.
(die Berechnung darin entspricht meiner ersten "falschen/ungewünschten" Formel)

Code:
[b]Function[/b] Gradient(ACanvas: TCanvas; Pos: TRect; const FromColor, [b]ThroughColor[/b], ToColor: TColor): Boolean;
  ...

Gradient(Canvas, Pos, clGreen, [b]clYellow[/b], clLime);
und wieso Cardinal? (TColor)

mr_emre_d 1. Feb 2009 00:19

Re: farbverlauf in %
 
TColor = Cardinal
bzw TColor = 4 unsigned Bytes

Und ja, die habe ich :P (pfeile grad noch rum, kann sie aber demnächst posten)

himitsu 1. Feb 2009 00:23

Re: farbverlauf in %
 
Zitat:

Zitat von mr_emre_d
Und ja, die habe ich :P (pfeile grad noch rum, kann sie aber demnächst posten)

na dann werden mal sehn :angel:

Zitat:

TColor = Cardinal
bzw TColor = 4 unsigned Bytes
wen es schon einen Typen dafür gibt, warum dann diesen nicht verwenden?

PS: TColor ist nicht Cardinal (ein Glück, daß die Meißten die Bereichprüfung nicht aktiv haben)
Delphi-Quellcode:
  TColor = -$7FFFFFFF-1..$7FFFFFFF;

mr_emre_d 1. Feb 2009 00:27

Re: farbverlauf in %
 
uupps .. :oops:
dann eben integer bzw signed 4 bytes :P

Edit:
Da hastes Himitsu:
Delphi-Quellcode:
function _inc(var x: Integer): Integer;
begin
  Result := x;
  inc(x);
end;

function Gradient2( ACanvas: TCanvas;
  Pos: TRect; const Colors: Array of Integer ): Boolean;
var
  x: Integer;
  NewColor: Integer;
  Percent: Single;
  rOP, gOP, bOP: Single; // One Percent
  cOldID, cID: Integer;
  xPercent, OnePercent: Cardinal;
begin
  Result := False;
  {Initialization}
  Pos.Right := Pos.Right - Pos.Left; // Right = Width
  Pos.Bottom := Pos.Bottom - Pos.Top; // Bottom = Height
  with ACanvas do
  begin
    cOldID    := -1;
    cID       := 0;
    xPercent  := High(Colors);
    if xPercent < 1 then
      Exit;
    OnePercent := Pos.Right div xPercent;
    for x := 1 to Pos.Right do
    begin
      if x-OnePercent >= OnePercent*cOLDID then
      begin
        cOldID := _inc(cID);
        rOP := (GetRValue(Colors[cID])-GetRValue(Colors[cOldID])) / OnePercent;
        gOP := (GetGValue(Colors[cID])-GetGValue(Colors[cOldID])) / OnePercent;
        bOP := (GetBValue(Colors[cID])-GetBValue(Colors[cOldID])) / OnePercent;
      end;
      NewColor := RGB(
        GetRValue(Colors[cOldID])+Round(rOP*(x mod OnePercent)),
        GetGValue(Colors[cOldID])+Round(gOP*(x mod OnePercent)),
        GetBValue(Colors[cOldID])+Round(bOP*(x mod OnePercent))
        );
      Pen.Color := NewColor;
      MoveTo( Pos.Left+x, Pos.Top );
      LineTo( Pos.Left+x, Pos.Top+Pos.Bottom );
    end;
  end;
  Result := not Result;
end;

mr_emre_d 1. Feb 2009 01:27

Re: farbverlauf in %
 
Man könnte das ganze mit Scanline und co machen aber dazu hab ich grad keine Lust :P

shmia 2. Feb 2009 09:49

Re: farbverlauf in %
 
Zitat:

Zitat von lbccaleb
das Problem ist ja, das ich nicht alle Farben auf die selbe Art berechnen kann, ich will ja nur nen Übergang hinnbekommen von Rot zu Gelb zu Grün!

Hast du dir den Beitrag in der Code-Library wirklich gut angeschaut?
Ganz besonders die 2. Funktion:
Delphi-Quellcode:
// Farbe zwischen beliebig vielen vorgegebenen Farbwerten berechnen
function ColorsBetween(colors:array of TColor; blend:Real):TColor;
Mit dieser Funktion kannst du die schönsten Farbverläufe berechnen.
Wenn du z.B. Rot nach Gelb zu Grün haben willst, dann wäre der Aufruf:
Delphi-Quellcode:
farbe := ColorsBetween([clRed, clYellow, clGreen], blendfaktor);
Ein Farbübergang zwischen Rot und Grün ohne Farbmischung erreicht man z.B. indem man Grau als mittlere Farbe einsetzt:
Delphi-Quellcode:
farbe := ColorsBetween([clRed, clGrey, Green], blendfaktor);
Ausserdem:
Also ich halte es für wichtig, dass man das Berechnen des Farbverlauf strikt vom Zeichen trennt.
Nur so kann man wirklich alle Möglichkeiten des Einfärben ausschöpfen.

lbccaleb 2. Feb 2009 16:56

Re: farbverlauf in %
 
Danke, aber mein Problem wurde bereits gelöst!

Ich habe genau das, was ich wollte, es soll genauso sein, bin also super zufrieden^^

PS ja, habe mir den Eintrag in der CodeLib angesehen, ist aber nicht das was ich wollte, denn daß wollte ich:


Zitat:

Zitat von lbccaleb
Joa danke, genau das wars was ich brauchte...
Danke..

Umgewandelt noch in eine Funktion (Math in Uses aufnehmen):

Delphi-Quellcode:
function GetColor(Prozent: integer): COLORREF;
  begin
    Result := RGB(255 * Min(100 - Prozent, 50) div 50, 255 * Min(Prozent, 50) div 50, 0);
  end;


shmia 2. Feb 2009 18:03

Re: farbverlauf in %
 
Liste der Anhänge anzeigen (Anzahl: 2)
Zitat:

Zitat von lbccaleb
... habe genau das, was ich wollte, es soll genauso sein, bin also super zufrieden^^

Nun die Funktion GetColor() macht doch nichts anderes als:
Delphi-Quellcode:
farbe := ColorsBetween([clRed, clYellow, TColor($00FF00)], prozent / 100.0);
Wenn du irgendwann mal die Farben Rot, Gelb und Grün ändern möchtest, dann bist du doch mit der ColorsBetween()-Funktion viel besser bedient.
Ausserdem liefert GetColor() stufige Farben, weil der Farbraum nicht komplett abgedeckt wird.
Mit ColorsBetween() bekommt man einen völlig gleichmässigen Farbverlauf.
Siehe Anhang - der untere Farbverlauf hat Stufen, der obere nicht.

himitsu 2. Feb 2009 19:01

Re: farbverlauf in %
 
@shmia: clLime = (Hell)Grün

lbccaleb 7. Feb 2009 18:01

Re: farbverlauf in %
 
Zitat:

Zitat von shmia
Wenn du irgendwann mal die Farben Rot, Gelb und Grün ändern möchtest, dann bist du doch mit der ColorsBetween()-Funktion viel besser bedient.

Ja, nur will ich diese nicht ändern, da die Festgelegt sein sollen!

Zitat:

Zitat von shmia
Ausserdem liefert GetColor() stufige Farben, weil der Farbraum nicht komplett abgedeckt wird.
Mit ColorsBetween() bekommt man einen völlig gleichmässigen Farbverlauf.
Siehe Anhang - der untere Farbverlauf hat Stufen, der obere nicht.

Ist richtig, aber für mein vorhaben total egal...

Ich hab das ganze in diesem Programm gebraucht:

Passwort Generator


Wirf mal ein blick rein, dann weißt warum die Funktion super i.O. für mich ist^^

mfg


Alle Zeitangaben in WEZ +1. Es ist jetzt 15:52 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