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

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

Не дубликат точный. HSL! = HSV.

Adam Rosenfield 11.12.2008 18:01

Что делать, чтобы адаптировать код из сообщения HSL для использования в решении HSV?

Tomasz Smykowski 11.12.2008 18:03

Википедия: оба математически цилиндрические, но HSV концептуально можно рассматривать как перевернутый конус цветов, HSL концептуально представляет собой двойной конус или сферу. Хотя «оттенок» в HSL и HSV относится к одному и тому же атрибуту, их определения «насыщенности» сильно различаются.

BlaM 11.12.2008 18:05

@ Адам: Я бы хотел, чтобы люди Paint.NET смогли это понять! :)

leppie 27.07.2009 14:56

Повторное повторение: HSV сильно отличается от HSL. HSV иногда называют HSB (особенно в Photoshop и .NET).

Ian Boyd 20.12.2009 18:45
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
66
5
110 152
6
Перейти к ответу Данный вопрос помечен как решенный

Ответы 6

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

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

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

найдено через Google

Эта реализация неверна. Кажется, это на основе этого примера кода, но в нем отсутствует раздел (часть нормализации). Если бы я споткнулся на какое-то время!

Dan Messing 09.08.2012 01:25
Ответ принят как подходящий

Рассматривали ли вы простое использование пространства имен 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, но последний разумно легко добавить.

Как вы заметили, это на самом деле не отвечает на вопрос, потому что эти методы обеспечивают преобразование RGB в HSL, а не RGB в HSV.

Greg 26.10.2009 20:38

@greg: Я согласен, это приведет к ужасным результатам, как я сам убедился.

leppie 05.11.2009 15:01

-1: Поскольку это не ответ на вопрос. HSV сильно отличается от HSL. Примечание: HSV иногда называют HSB (особенно в Photoshop и .NET).

Ian Boyd 20.12.2009 18:44

Я не уверен, в чем разница между легкостью, яркостью и ценностью (всегда думал, что это синонимы), но, глядя на реализацию System.Drawing.Color, я вижу, что она не основана на весах NTSC для красного, зеленого и синего, но рассматривает их все то же самое, что дает неоптимальные результаты.

Itai Bar-Haim 21.05.2013 19:54

@IanBoyd Хотя то, что вы говорите по поводу. HSV, HSL и HSB верны, проблема в том, что реализация HSB в System.Drawing, на самом деле, кажется неправильным: они реализовали HSL. В .NET API указано, что Color.GetBrightness()возвращает легкость, а не значение (т.е. это не «V» в HSV, а «L» в HSL).

Informagic 08.09.2019 01:12

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

There's a C implementation here:

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

Should be very straightforward to convert to C#, as almost no functions are called - just > calculations.


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

Обратите внимание, что 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);
}

Я думаю, вы перенесли образцы значений насыщенности и значения в свой ответ. Когда я конвертирую rgb (50,120,200) в значение Hue-Saturation-Value (HSV), я получаю hsv (212, 75%, 78,4%). Глядя на формулы Википедии для HSV: V = Max (r, g, b). В этом случае max (50,120,200) = 200. 200/255 = 0,7843

Ian Boyd 20.12.2009 19:13

я просто отредактирую ответ, транспонировав числа Saturation и Value. Насыщенность должна быть 0,75, значение должно быть 0,7843 ...

Ian Boyd 20.12.2009 19:16

Есть идеи, как преобразовать насыщенность от 0 до 1 в значение насыщенности, которое использует MS Paint (например, шкала 0–240)?

Jake Drew 01.01.2016 05:26

Отличный ответ! Может быть, подумайте об использовании float вместо double, чтобы соответствовать тому, что возвращает .NET color.GetHue ()?

user1032613 24.04.2016 02:38

Не знаю, делаю ли я что-то не так, но эта пара функций мне не подходит. Выполнение ToHSV(FromHSV(32,1, 1)) возвращает 32, но ToHSV(FromHSV(33,1, 1)) возвращает 32.9411773. ToHSV(FromHSV(34,1, 1)) возвращает 33.8823547. ToHSV(FromHSV(35,1, 1)) возвращает 35.0588264. ToHSV(FromHSV(36,1, 1)) снова возвращает 36. Похоже, что кратные 4 работают правильно, в то время как другие смещены на кратные 1/17. Я понятия не имею, откуда взялось это магическое число.

dotNET 28.11.2017 19:31

Понятно. Переменные HSV используют тип double, который имеет гораздо более высокую степень детализации, чем те, которые могут содержать 8-битные каналы RGB. Поэтому 100% -ное двустороннее отображение невозможно. Однако мне интересно узнать, можно ли улучшить эти функции для безопасной работы с подмножеством RGB.

dotNET 29.11.2017 08:00

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

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

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

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

То, что я сделал, когда у меня возникла эта проблема недавно, я сначала получил значения 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 :)

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

Это не HSV, а HSL. stackoverflow.com/questions/15668623/hsb-vs-hsl-vs-hsv

Sha 21.09.2018 14:01

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