Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   Farben sortieren (https://www.delphipraxis.net/37715-farben-sortieren.html)

toms 9. Jan 2005 12:33


Farben sortieren
 
Hi,

Hat jemand einen Ansatz od Algorithmus, um Farben zu sortieren?
Farben sollen von hell nach dunkel sortiert werden, wobei
gleiche Farbetoene hintereinander liegen sollen.

OregonGhost 9. Jan 2005 13:11

Re: Farben sortieren
 
Reicht dann nicht eine HSB-Betrachtung für die Farbe? Da hast du doch schon deinen Farbton und deine Helligkeit, und dann danach zu sortieren ist ja wohl trivial ;c)

Falls es an der Umwandlung in HSB scheitert:
Die .NET-Struktur Color bietet direkt die Umwandlung bzw. das Auslesen der Werte an, und für's Selber-Umwandeln findest du alle Infos im efg Lab oder hier.

toms 10. Jan 2005 06:22

Re: Farben sortieren
 
Danke fuere deine Antwort!

Jedoch sieht die Sortierung mit HSB nicht wirklich zufriedenstellend aus.
Mein Testcode:

Delphi-Quellcode:
function getBrightness(R, G, B: BYTE): BYTE;
begin
  Result := TRUNC(R * 0.3 + G * 0.59 + B * 0.11);
end;

function CalculateLuminance(R, G, B: BYTE): BYTE;
const
  R_FACTOR = 0.2126;
  G_FACTOR = 0.7152;
  B_FACTOR = 0.0722;
begin
  Result := TRUNC(R * R_FACTOR + G * G_FACTOR + B * B_FACTOR);
end;

procedure RGBTripleToHSV(const RGBTriple: TRGBTriple; {r, g and b IN [0..255]}
  var H, S, V: INTEGER); {h IN 0..359; s,v IN 0..255}
var
  Delta: INTEGER;
  Min: INTEGER;
begin
  with RGBTriple do
  begin
    Min := MinIntValue([rgbtRed, rgbtGreen, rgbtBlue]);
    V := MaxIntValue([rgbtRed, rgbtGreen, rgbtBlue])
  end;

  Delta := V - Min;

    // Calculate saturation: saturation is 0 if r, g and b are all 0
  if V = 0
    then S := 0
  else S := MulDiv(Delta, 255, V);

  if S = 0
    then H := 0 // Achromatic: When s = 0, h is undefined but assigned the value 0
  else begin // Chromatic

    with RGBTriple do
    begin
      if rgbtRed = V
        then // degrees -- between yellow and magenta
        H := MulDiv(rgbtGreen - rgbtBlue, 60, Delta)
      else
        if rgbtGreen = V
          then // between cyan and yellow
          H := 120 + MulDiv(rgbtBlue - rgbtRed, 60, Delta)
        else
          if rgbtBlue = V
            then // between magenta and cyan
            H := 240 + MulDiv(rgbtRed - rgbtGreen, 60, Delta);
    end;

    if H < 0
      then H := H + 360;

  end
end {RGBTripleToHSV};


function SortBackwards(List: TStringList; Index1, Index2: Integer): integer;
var
  r1, g1, b1, r2, g2, b2: DWORD;
  COLOR1, COLOR2: Tcolor;
  t1, t2: TRGBTriple;
  H1, S1, V1: INTEGER;
  H2, S2, V2: INTEGER;
begin
  COLOR1 := stringtocolor(List[Index1]);
  COLOR2 := stringtocolor(List[Index2]);

  R1 := GetRValue(COLOR1);
  G1 := GetGValue(COLOR1);
  B1 := GetBValue(COLOR1);

  R2 := GetRValue(COLOR2);
  G2 := GetGValue(COLOR2);
  B2 := GetBValue(COLOR2);

  t1.rgbtBlue := b1;
  t1.rgbtGreen := g1;
  t1.rgbtRed := r1;
  RGBTripleToHSV(t1, H1, S1, V1);

  t2.rgbtBlue := b2;
  t2.rgbtGreen := g2;
  t2.rgbtRed := r2;
  RGBTripleToHSV(t2, H2, S2, V2);
  Result := AnsiCompareStr(inttostr(S1), inttostr(S2));
 // Result := AnsiCompareStr(inttostr(V1), inttostr(V2));
 // Result := AnsiCompareStr(inttostr(CalculateLuminance(r1, g1, b1)), inttostr(CalculateLuminance(r2, g2, b2)));
end;


procedure TForm1.Button1Click(Sender: TObject);
var
  SortedStringList: TStringList;
begin
  SortedStringList := nil;
  try
    SortedStringList := TStringList.Create;
    SortedStringList.Assign(memo1.lines);
    SortedStringList.CustomSort(SortBackwards);

    memo1.lines.Clear;
    memo1.lines.Assign(SortedStringList);
  finally
    SortedStringList.Free;
  end;

end;
Meine html Farben:

6699CC
FF0000
000000
33CC99
F5DEB3
FDF5E6
ADD8E6
00BFFF
FF7F50
DCDCDC
90EE90
D8BFD8
FFE4E1
E0FFFF
E9967A
FFEBCD
99FFCC
CCCC99
CCCCCC
00000FF
CCCCFF
CCFF99
CCFFCC
CCFFFF
FFCC99
FFCCCC
FFCCFF
FFFF99
FFFFCC
FFFFFF

Muetze1 10. Jan 2005 08:21

Re: Farben sortieren
 
Moin!

Delphi-Quellcode:
Result := AnsiCompareStr(inttostr(S1), inttostr(S2));
Hä? Du willst 2 Integer vergleichen und wandelst sie daher in einen String um, um sie dann zu vergleichen? Hä? Wenn der eine Wert 2 stellig ist und der andere 3 stellig, dann wird das bei einem Stringvergleich aber nicht ordentlich beachtet. Warum vergleichst du nicht direkt?

Delphi-Quellcode:
Result := Min(1, Max(-1, S1 - S2));
Und von deiner HTML Farbenliste darfst du aber dann nicht mehr erwarten, das am Ende alle Farben mit FF am Anfang auftauchen, da er über die Helligkeit geht...

MfG
Muetze1

toms 10. Jan 2005 13:13

Re: Farben sortieren
 
Zitat:

Zitat von Muetze1
Moin!
Warum vergleichst du nicht direkt?

Na ja, hatte gestern wohl den Kopf nicht so bei der Sache.
Danke, werde mal deinen Vorschlag ausprobieren.


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