Как изменить цвет RGB на HSV?

Как изменить цвет RGB на HSV? На языке C#. Я ищу очень быстрый метод без какой-либо внешней библиотеки.

7 ответов

Решение

Рассматривали ли вы просто использование пространства имен System.Drawing? Например:

System.Drawing.Color color = System.Drawing.Color.FromArgb(red, green, blue);
float hue = color.GetHue();
float saturation = color.GetSaturation();
float lightness = color.GetBrightness();

Обратите внимание, что это не совсем то, о чем вы просили (см. Различия между HSL и HSV, и класс Color не имеет преобразования обратно из HSL/HSV, но последний довольно легко добавить.

Обратите внимание, что Color.GetSaturation() а также Color.GetBrightness() вернуть значения HSL, а не HSV.
Следующий код демонстрирует разницу.

Color original = Color.FromArgb(50, 120, 200);
// original = {Name=ff3278c8, ARGB=(255, 50, 120, 200)}

double hue;
double saturation;
double value;
ColorToHSV(original, out hue, out saturation, out value);
// hue        = 212.0
// saturation = 0.75
// value      = 0.78431372549019607

Color copy = ColorFromHSV(hue, saturation, value);
// copy = {Name=ff3278c8, ARGB=(255, 50, 120, 200)}

// Compare that to the HSL values that the .NET framework provides: 
original.GetHue();        // 212.0
original.GetSaturation(); // 0.6
original.GetBrightness(); // 0.490196079

Следующий код C# - это то, что вы хотите. Он конвертирует между RGB и HSV, используя алгоритмы, описанные в Википедии. Диапазоны 0 - 360 для hueи 0 - 1 для saturation или же value,

public static void ColorToHSV(Color color, out double hue, out double saturation, out double value)
{
    int max = Math.Max(color.R, Math.Max(color.G, color.B));
    int min = Math.Min(color.R, Math.Min(color.G, color.B));

    hue = color.GetHue();
    saturation = (max == 0) ? 0 : 1d - (1d * min / max);
    value = max / 255d;
}

public static Color ColorFromHSV(double hue, double saturation, double value)
{
    int hi = Convert.ToInt32(Math.Floor(hue / 60)) % 6;
    double f = hue / 60 - Math.Floor(hue / 60);

    value = value * 255;
    int v = Convert.ToInt32(value);
    int p = Convert.ToInt32(value * (1 - saturation));
    int q = Convert.ToInt32(value * (1 - f * saturation));
    int t = Convert.ToInt32(value * (1 - (1 - f) * saturation));

    if (hi == 0)
        return Color.FromArgb(255, v, t, p);
    else if (hi == 1)
        return Color.FromArgb(255, q, v, p);
    else if (hi == 2)
        return Color.FromArgb(255, p, v, t);
    else if (hi == 3)
        return Color.FromArgb(255, p, q, v);
    else if (hi == 4)
        return Color.FromArgb(255, t, p, v);
    else
        return Color.FromArgb(255, v, p, q);
}

EasyRGB имеет много преобразований цветового пространства. Вот код для преобразования RGB->HSV.

Здесь есть реализация C:

http://www.cs.rit.edu/~ncs/color/t_convert.html

Преобразование в C# должно быть очень простым, так как функции почти не вызываются - только вычисления.

найден через гугл

Это версия VB.net, которая отлично работает для меня, перенесена из кода C в посте BlaM.

Здесь есть реализация C:

http://www.cs.rit.edu/~ncs/color/t_convert.html

Преобразование в C# должно быть очень простым, так как функции почти не вызываются - просто> вычисления.


Public Sub HSVtoRGB(ByRef r As Double, ByRef g As Double, ByRef b As Double, ByVal h As Double, ByVal s As Double, ByVal v As Double)
    Dim i As Integer
    Dim f, p, q, t As Double

    If (s = 0) Then
        ' achromatic (grey)
        r = v
        g = v
        b = v
        Exit Sub
    End If

    h /= 60 'sector 0 to 5
    i = Math.Floor(h)
    f = h - i 'factorial part of h
    p = v * (1 - s)
    q = v * (1 - s * f)
    t = v * (1 - s * (1 - f))

    Select Case (i)
        Case 0
            r = v
            g = t
            b = p
            Exit Select
        Case 1
            r = q
            g = v
            b = p
            Exit Select
        Case 2
            r = p
            g = v
            b = t
            Exit Select
        Case 3
            r = p
            g = q
            b = v
            Exit Select
        Case 4
            r = t
            g = p
            b = v
            Exit Select
        Case Else   'case 5:
            r = v
            g = p
            b = q
            Exit Select
    End Select
End Sub

Я оказался здесь из-за той же потребности.

Ниже я поделюсь лучшим и более простым решением, которое я смог найти до сих пор.
Это модифицированный ответ Грега ( ); но с более скромным и понятным кодом.

Для тех, кто учится, я добавил несколько ссылок, которые стоит проверить для понимания.


использованная литература

  1. Инструмент для моделирования HSV "Лукас Стратманн" (включая другие модельные системы: CMY / CMYK / HSL)
  2. «Цветовая модель HSV в графическом дизайне»
  3. «Формула для определения воспринимаемой яркости цвета RGB»
  4. Самая быстрая формула для получения оттенка из RGB
  5. «Алгоритмы преобразования цвета»
  6. «Программа для изменения цветовой модели RGB на цветовую модель HSV»
  7. «Алгоритм преобразования цвета RGB в HSV»
  8. «Преобразование цветового пространства RGB в HSV (C)»
  9. найден здесь«Как преобразовать цвет RGB в HSV»

Код

          /// <summary> Convert RGB Color to HSV. </summary>
    /// <param name="color"></param>
    /// <returns> A double[] Containing HSV Color Values. </returns>
    public double[] rgbToHSV(Color color)
    {
        double[] output = new double[3];

        double hue, saturation, value;

        int max = Math.Max(color.R, Math.Max(color.G, color.B));
        int min = Math.Min(color.R, Math.Min(color.G, color.B));

        hue = color.GetHue();
        saturation = (max == 0) ? 0 : 1d - (1d * min / max);
        value = max / 255d;

        output[0] = hue;
        output[1] = saturation;
        output[2] = value;

        return output;
    }

ПЕРВЫЙ: убедитесь, что у вас есть цвет в виде растрового изображения, например:

Bitmap bmp = (Bitmap)pictureBox1.Image.Clone();
paintcolor = bmp.GetPixel(e.X, e.Y);

(Он из обработчика событий, который выбрал мой цвет!)

То, что я сделал, когда у меня была эта проблема некоторое время назад, я сначала получил значения rgba (красный, зеленый, синий и альфа). Затем я создал 3 поплавка: цвет поплавка, насыщенность поплавка, яркость поплавка. Тогда вы просто делаете:

hue = yourcolor.Gethue;
saturation = yourcolor.GetSaturation;
brightness = yourcolor.GetBrightness;

Вся партия выглядит так:

Bitmap bmp = (Bitmap)pictureBox1.Image.Clone();
            paintcolor = bmp.GetPixel(e.X, e.Y);
            float hue;
            float saturation;
            float brightness;
            hue = paintcolor.GetHue();
            saturation = paintcolor.GetSaturation();
            brightness = paintcolor.GetBrightness();

Если вы хотите отобразить их в метке, просто выполните:

yourlabelname.Text = hue.ToString;
yourlabelname.Text = saturation.ToString;
yourlabelname.Text = brightness.ToString;

Вот, пожалуйста, теперь у вас есть значения RGB в значениях HSV:)

Надеюсь это поможет

Другие вопросы по тегам