Frage

In PHP, was ist der einfachste Weg, um ein RGB-Triplett zu HSV-Wert zu konvertieren?

War es hilfreich?

Lösung

<?php
function RGB_TO_HSV ($R, $G, $B)  // RGB Values:Number 0-255
{                                 // HSV Results:Number 0-1
   $HSL = array();

   $var_R = ($R / 255);
   $var_G = ($G / 255);
   $var_B = ($B / 255);

   $var_Min = min($var_R, $var_G, $var_B);
   $var_Max = max($var_R, $var_G, $var_B);
   $del_Max = $var_Max - $var_Min;

   $V = $var_Max;

   if ($del_Max == 0)
   {
      $H = 0;
      $S = 0;
   }
   else
   {
      $S = $del_Max / $var_Max;

      $del_R = ( ( ( $var_Max - $var_R ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
      $del_G = ( ( ( $var_Max - $var_G ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;
      $del_B = ( ( ( $var_Max - $var_B ) / 6 ) + ( $del_Max / 2 ) ) / $del_Max;

      if      ($var_R == $var_Max) $H = $del_B - $del_G;
      else if ($var_G == $var_Max) $H = ( 1 / 3 ) + $del_R - $del_B;
      else if ($var_B == $var_Max) $H = ( 2 / 3 ) + $del_G - $del_R;

      if ($H<0) $H++;
      if ($H>1) $H--;
   }

   $HSL['H'] = $H;
   $HSL['S'] = $S;
   $HSL['V'] = $V;

   return $HSL;
}

Andere Tipps

Hier ist eine einfache, unkomplizierte Methode, dass die Renditen Werte als Grad und Prozent HSV, das, was Farbauswahl Anwendungen Photoshop ist.

Beachten Sie, dass die Rückgabewerte nicht gerundet sind, können Sie das selbst tun, wenn erforderlich. Beachten Sie, dass H(360) == H(0), so H Werte von 359.5 und größer sollte rund um 0

Stark dokumentiert zu Lernzwecken.

/**
 * Licensed under the terms of the BSD License.
 * (Basically, this means you can do whatever you like with it,
 *   but if you just copy and paste my code into your app, you
 *   should give me a shout-out/credit :)
 */

<?php

function RGBtoHSV($R, $G, $B)    // RGB values:    0-255, 0-255, 0-255
{                                // HSV values:    0-360, 0-100, 0-100
    // Convert the RGB byte-values to percentages
    $R = ($R / 255);
    $G = ($G / 255);
    $B = ($B / 255);

    // Calculate a few basic values, the maximum value of R,G,B, the
    //   minimum value, and the difference of the two (chroma).
    $maxRGB = max($R, $G, $B);
    $minRGB = min($R, $G, $B);
    $chroma = $maxRGB - $minRGB;

    // Value (also called Brightness) is the easiest component to calculate,
    //   and is simply the highest value among the R,G,B components.
    // We multiply by 100 to turn the decimal into a readable percent value.
    $computedV = 100 * $maxRGB;

    // Special case if hueless (equal parts RGB make black, white, or grays)
    // Note that Hue is technically undefined when chroma is zero, as
    //   attempting to calculate it would cause division by zero (see
    //   below), so most applications simply substitute a Hue of zero.
    // Saturation will always be zero in this case, see below for details.
    if ($chroma == 0)
        return array(0, 0, $computedV);

    // Saturation is also simple to compute, and is simply the chroma
    //   over the Value (or Brightness)
    // Again, multiplied by 100 to get a percentage.
    $computedS = 100 * ($chroma / $maxRGB);

    // Calculate Hue component
    // Hue is calculated on the "chromacity plane", which is represented
    //   as a 2D hexagon, divided into six 60-degree sectors. We calculate
    //   the bisecting angle as a value 0 <= x < 6, that represents which
    //   portion of which sector the line falls on.
    if ($R == $minRGB)
        $h = 3 - (($G - $B) / $chroma);
    elseif ($B == $minRGB)
        $h = 1 - (($R - $G) / $chroma);
    else // $G == $minRGB
        $h = 5 - (($B - $R) / $chroma);

    // After we have the sector position, we multiply it by the size of
    //   each sector's arc (60 degrees) to obtain the angle in degrees.
    $computedH = 60 * $h;

    return array($computedH, $computedS, $computedV);
}

?>

gründlich getestet und komprimiert, ist dies die Funktion ich Stick mit gehe zum Umwandeln von RGB HSV :

function RGBtoHSV($r,$g,$b) {
  $r=($r/255); $g=($g/255); $b=($b/255);
  $maxRGB=max($r,$g,$b); $minRGB=min($r,$g,$b); $chroma=$maxRGB-$minRGB;
  if($chroma==0) return array('h'=>0,'s'=>0,'v'=>$maxRGB);
  if($r==$minRGB)$h=3-(($g-$b)/$chroma);
  elseif($b==$minRGB)$h=1-(($r-$g)/$chroma); else $h=5-(($b-$r)/$chroma);
  return array('h'=>60*$h,'s'=>$chroma/$maxRGB,'v'=>$maxRGB);
} 

Beispiel:

Beispiel unter Verwendung von Farbe " DarkSalmon ":

echo '<pre><code>'. print_r( RGBtoHSV(233,150,122), true ) .'</code></pre>';

... Rückkehr:

Array
(
    [h] => 15.135135135135
    [s] => 0.47639484978541
    [v] => 0.91372549019608
)

Ich habe es wie folgt

function convertRgbToHsv($rgb)
{

    $r = (int)substr($rgb, 0, 3) / 255;
    $g = (int)substr($rgb, 3, 3) / 255;
    $b = (int)substr($rgb, 6, 3) / 255;

    $max = max($r, $g, $b);
    $min = min($r, $g, $b);
    $delta = $max - $min;

    if (!$delta) {
        $h = 0;
    } else if ($r === $max) {
        $h = 60 * ((($g - $b) / $delta) % 6);
    } else if ($g === $max) {
        $h = 60 * ((($b - $r) / $delta) + 2);
    } else {
        $h = 60 * ((($r - $g) / $delta) + 4);
    }

    $s = !!$max ? $delta / $max : 0;

    $v = $max;

    $hsv = array("h" => $h, "s" => $s, "v" => $v);

    return $hsv;
}

Link zum Referenzmaterial hier

Hier ist mein Spin auf sich, zusammen mit einem Gerät zu testen. Da die S und V Werte sind Prozentsätze, dieser Code gibt sie als ganze Zahlen (0, 100) im Gegensatz zu (0, 1) -. Beispiel, 75 statt 0.75

final class MathService
{    
    /**
     * Converts an RGB point into HSV
     *
     * @param int $r
     * @param int $g
     * @param int $b
     * @return array
     */
    public function rgbToHsv(int $r, int $g, int $b): array
    {
        $rPrime = $r / 255;
        $gPrime = $g / 255;
        $bPrime = $b / 255;

        $max = max([$rPrime, $gPrime, $bPrime]);
        $min = min([$rPrime, $gPrime, $bPrime]);

        $delta = $max - $min;

        // Calculate H
        if ($delta == 0) {
            $h = 0;
        } else {
            if ($max === $rPrime) {
                $h = 60 * ((($gPrime - $bPrime) / $delta) % 6);
            }
            if ($max === $gPrime) {
                $h = 60 * ((($bPrime - $rPrime) / $delta) + 2);
            }
            if ($max === $bPrime) {
                $h = 60 * ((($rPrime - $gPrime) / $delta) + 4);
            }
        }

        // Calculate S
        if ($max == 0) {
            $s = 0;
        } else {
            $s = $delta / $max;
        }

        // Calculate V
        $v = $max;

        return [$h, (int)($s * 100), (int)($v * 100)];
    }
}

PHPUnit Testfall mit PHP 7.2

/**
 * @test
 */
public function rgbToHsv_ComputesCorrectValues(): void
{
    $service = new MathService();
    $samples = [
        // [R, G, B, H, S, V]
        [0, 0, 0, 0, 0, 0],
        [255, 255, 255, 0, 0, 100],
        [255, 0, 0, 0, 100, 100],
        [0, 255, 0, 120, 100, 100],
        [0, 0, 255, 240, 100, 100],
        [255, 255, 0, 60, 100, 100],
        [0, 255, 255, 180, 100, 100],
        [255, 0, 255, 300, 100, 100],
        [192, 192, 192, 0, 0, 75],
        [128, 128, 128, 0, 0, 50],
        [128, 0, 0, 0, 100, 50],
        [128, 128, 0, 60, 100, 50],
        [0, 128, 0, 120, 100, 50],
        [128, 0, 128, 300, 100, 50],
        [0, 128, 128, 180, 100, 50],
        [0, 0, 128, 240, 100, 50],
    ];

    foreach ($samples as $sample) {
        list($r, $g, $b) = array_slice($sample, 0, 3);
        $expected = array_slice($sample, 3);
        $hsv = $service->rgbToHsv($r, $g, $b);
        list($h, $s, $v) = $hsv;

        self::assertEquals($expected, $hsv, "Error converting ({$r}, ${g}, ${b}). Got ({$h}, {$s}, {$v})");
    }
}
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top