Einzelnen Beitrag anzeigen

Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
44.184 Beiträge
 
Delphi 12 Athens
 
#5

Re: Darstellung von Falschfarben

  Alt 26. Jan 2010, 09:49
Jupp, Vorteil ist auch, daß beim HSV der Wertebereich von "Hue"/Farbe weitaus größer als nur 256 ist.

http://www.delphipraxis.net/internal...&highlight=hsv


Bei meiner Implementation hatte ich damals für Hue einen Wertebereich von 0 bis 65520 gewählt.
(macht 182 Schritte pro Grad)

In dem verlinken CL-Eintrag geht es bei Hue "nur" von 0 bis 360, welches dir vermutlich nicht ausreichen wird.

Delphi-Quellcode:
(******************************************************************************************** )
(                                                                                            )
(  THSVRec (Hue, Saturation, Value) and THSBRec (Hue, Saturation, Brightness):                )
(  ***************************************************************************                )
(                                                                                            )
(  THSVRec/THSBRec = Record Case Byte of                                                      )
(    0: (Org: THSV);                                                                          )
(    1: (Hue: Word; Saturation, Brightness: Byte);                                            )
(    ...                                                                                      )
(  End;                                                                                      )
(                                                                                            )
(  Hue              =  0..65520  >  X * ~180  >  0..360°                                    )
(  Saturation        =  0..256    >  X * 2.56  >  0..100%                                    )
(  Brightness\Value  =  0..256    >  X * 2.56  >  0..100%                                    )
(                                                                                            )
(  Hue:    0° = Red        60° = Yellow                                                      )
(        120° = Green    180° = Cyan                                                        )
(        240° = Blue      300° = Magenta                                                      )
(                                                                                            )
(                                                                                            )
(  Known also still as HLS (Hue, Luminance, Saturation)  =>  Luminance = Brightness\Value    )
(                                                                                            )
(*********************************************************************************************)


Type THSB = Type LongWord;
  THSV = THSB;

  PHSB = ^THSB;
  PHSV = PHSB;

  THSBRec = packed Record Case Byte of
    0: (Org: THSB);
    1: (Hue: Word; Saturation, Brightness: Byte);
    4: (Bin: LongWord);
    6: (Bits: TLongWordSet);
    7: (Bytes: TByteArray4);
    8: (Words: TWordArray2);
  End;
  THSVRec = THSBRec;

Function RGBtoHSV(RGB: TColor): THSV;
Function HSVtoRGB(HSV: THSV): TColor;



Function RGBtoHSV(RGB: TColor): THSV;
  Var _RGB: TColorRec Absolute RGB;
    _HSV: THSVRec Absolute Result;
    Darkness: Byte;
    H: LongInt;

  Begin
    RGB := ColorToRGB(RGB);
    If _RGB.Red > _RGB.Green Then _HSV.Brightness := _RGB.Red Else _HSV.Brightness := _RGB.Green;
    If _RGB.Blue > _HSV.Brightness Then _HSV.Brightness := _RGB.Blue;
    If _RGB.Red < _RGB.Green Then Darkness := _RGB.Red Else Darkness := _RGB.Green;
    If _RGB.Blue < Darkness Then Darkness := _RGB.Blue;
    If _HSV.Brightness = 0 Then _HSV.Saturation := 0
    Else _HSV.Saturation := MulDiv(_HSV.Brightness - Darkness, 255, _HSV.Brightness);
    If _HSV.Saturation <> 0 Then Begin
      If _RGB.Red = _HSV.Brightness Then H := Round((_RGB.Green - _RGB.Blue) / (_HSV.Brightness - Darkness) * 10920)
      Else If _RGB.Green = _HSV.Brightness Then H := Round(21840 + (_RGB.Blue - _RGB.Red) / (_HSV.Brightness - Darkness) * 10920)
      Else H := Round(43680 + (_RGB.Red - _RGB.Green) / (_HSV.Brightness - Darkness) * 10920);
      If H >= 0 Then _HSV.Hue := H Else _HSV.Hue := H + 65520;
    End Else _HSV.Hue := 0;
  End;

Function BGRtoHSV(RGB: TBGRRec): THSVRec;
  Var Darkness: Byte;
    H: LongInt;

  Begin
    If RGB.Red > RGB.Green Then Result.Brightness := RGB.Red Else Result.Brightness := RGB.Green;
    If RGB.Blue > Result.Brightness Then Result.Brightness := RGB.Blue;
    If RGB.Red < RGB.Green Then Darkness := RGB.Red Else Darkness := RGB.Green;
    If RGB.Blue < Darkness Then Darkness := RGB.Blue;
    If Result.Brightness = 0 Then Result.Saturation := 0
    Else Result.Saturation := MulDiv(Result.Brightness - Darkness, 255, Result.Brightness);
    If Result.Saturation <> 0 Then Begin
      If RGB.Red = Result.Brightness Then H := Round((RGB.Green - RGB.Blue) / (Result.Brightness - Darkness) * 10920)
      Else If RGB.Green = Result.Brightness Then H := Round(21840 + (RGB.Blue - RGB.Red) / (Result.Brightness - Darkness) * 10920)
      Else H := Round(43680 + (RGB.Red - RGB.Green) / (Result.Brightness - Darkness) * 10920);
      If H >= 0 Then Result.Hue := H Else Result.Hue := H + 65520;
    End Else Result.Hue := 0;
  End;

Function HSVtoRGB(HSV: THSV): TColor;
  Var _RGB: TColorRec Absolute Result;
    _HSV: THSVRec Absolute HSV;

  Begin
    _RGB.Palette := cpSystemPalette;
    If _HSV.Saturation <> 0 Then Begin
      If _HSV.Hue >= 54600 Then Begin
        _RGB.Red := _HSV.Brightness;
        _RGB.Green := MulDiv(_HSV.Brightness, not _HSV.Saturation, 255);
        _RGB.Blue := Round(_HSV.Brightness * (255 - _HSV.Saturation * (_HSV.Hue mod 10920) / 10920) / 255);
      End Else If _HSV.Hue >= 43680 Then Begin
        _RGB.Red := Round(_HSV.Brightness * (255 - _HSV.Saturation * (10920 - (_HSV.Hue mod 10920)) / 10920) / 255);
        _RGB.Green := MulDiv(_HSV.Brightness, not _HSV.Saturation, 255);
        _RGB.Blue := _HSV.Brightness;
      End Else If _HSV.Hue >= 32760 Then Begin
        _RGB.Red := MulDiv(_HSV.Brightness, not _HSV.Saturation, 255);
        _RGB.Green := Round(_HSV.Brightness * (255 - _HSV.Saturation * (_HSV.Hue mod 10920) / 10920) / 255);
        _RGB.Blue := _HSV.Brightness;
      End Else If _HSV.Hue >= 21840 Then Begin
        _RGB.Red := MulDiv(_HSV.Brightness, not _HSV.Saturation, 255);
        _RGB.Green := _HSV.Brightness;
        _RGB.Blue := Round(_HSV.Brightness * (255 - _HSV.Saturation * (10920 - (_HSV.Hue mod 10920)) / 10920) / 255);
      End Else If _HSV.Hue >= 10920 Then Begin
        _RGB.Red := Round(_HSV.Brightness * (255 - _HSV.Saturation * (_HSV.Hue mod 10920) / 10920) / 255);
        _RGB.Green := _HSV.Brightness;
        _RGB.Blue := MulDiv(_HSV.Brightness, not _HSV.Saturation, 255);
      End Else Begin
        _RGB.Red := _HSV.Brightness;
        _RGB.Green := Round(_HSV.Brightness * (255 - _HSV.Saturation * (10920 - (_HSV.Hue mod 10920)) / 10920) / 255);
        _RGB.Blue := MulDiv(_HSV.Brightness, not _HSV.Saturation, 255);
      End;
    End Else Begin
      _RGB.Red := _HSV.Brightness;
      _RGB.Green := _HSV.Brightness;
      _RGB.Blue := _HSV.Brightness;
    End;
  End;
$2B or not $2B
  Mit Zitat antworten Zitat