Как нарисовать хорошую карту цветов RGB? - PullRequest
12 голосов
/ 08 июня 2011

Я пытаюсь нарисовать полную цветовую карту RGB, которая в конечном итоге позволит пользователю выбрать цвет, коснувшись этой визуальной карты в любой точке. Мой текущий код следующий:

- (void)drawRect:(CGRect)rect
{
    CGContextRef c = UIGraphicsGetCurrentContext();

    for (float x=0; x<320; x++) {
        for (float y=0; y<416; y++) {

            float r = x / 320;
            float g = y / 416;
            float b = (y < 208) ? y / 208 : (416 - y) / 208;

            CGContextSetRGBFillColor(c, r, g, b, 1.0);
            CGContextFillRect(c, CGRectMake(x, y, 1, 1));

        }
    }
}

Результат не так уж и плох, но я еще не удовлетворен. Спектр пропускает яркие цвета, включая белый. Причина понятна: красный, зеленый и синий никогда не достигнут 1,0 одновременно.

Screenshot of the resulting color map

Есть ли у вас какие-либо советы, как улучшить эту карту, чтобы она представляла полный спектр цветового пространства RGB?

Спасибо за ваш вклад!

UPDATE:

Как подсказал Джош Касвелл Я использовал цветовое пространство HSB и следующий код:

- (void)drawRect:(CGRect)rect
{
    CGContextRef c = UIGraphicsGetCurrentContext();

    int size = 20;

    for (float x=0; x<320; x+=size) {

        float s = x < 160 ? 1       : (320 - x) / 160;
        float b = x < 160 ? x / 160 : 1;

        for (float y=0; y<416; y+=size) {

            float h = y / 416;

            [[UIColor colorWithHue:h saturation:s brightness:b alpha:1.0] setFill];
            CGContextFillRect(c, CGRectMake(x, y, size, size));
        }
    }
}

Это приводит к следующему выводу, который идеально подходит для моих нужд.

Result using HSB color space

Спасибо за все комментарии!

Ответы [ 3 ]

7 голосов
/ 08 июня 2011

Ну, вы пытаетесь сгладить трехмерный объект на плоскости. Цвет RGB в основном представляет точку внутри куба. Отображение твердого тела RGB на поверхность может быть математически возможным, но, вероятно, не будет особенно интуитивно понятным для этой цели выбора цвета.

Возможно, вам повезет больше, если использовать HSB, который больше похож на цилиндр с оттенком в качестве угла по окружности. Вы можете «развернуть» цилиндр, сопоставив оттенок с координатой y, а затем изменить яркость или насыщенность по оси x - вы можете провести простое тестирование, чтобы решить, какой компонент более важен для вашего приложения. Для третьего компонента можно использовать два пальца, если вы считаете, что его необходимо включить.

HSB с насыщением по оси X:
HSB map; S on X axis

С яркостью по оси X:
HSB map; B on X axis

С насыщенностью и яркостью, равными и по оси X:
HSB map; S=B on X axis

Если вам нужен белый цвет, который возникает, когда S = 0%, B = 100%, вы можете либо наклеить полоску вдоль одной стороны, либо попробовать S = 1 / B.

2 голосов
/ 08 июня 2011

Вы пытаетесь представить 3-мерное цветовое пространство на 2-мерной поверхности. Маловероятно, что вы найдете подходящую поверхность.

Вам понадобится выбор из двух частей.

2 голосов
/ 08 июня 2011

Я думаю, что способ вывести его таков:

По горизонтали для каждого пикселя выберите соотношение r g b, например, «0, 0, 1»

Нарисуйте пиксели сверху вниз с «яркостью», которая изменяется от 0 до 1.

Вывести каждый пиксель как pixel = brightness * (r,g,b)

Когда вы идете горизонтально, итерируйте R G B как:

000, 001, 010, 011, 100, 101, 110, 111

Вы можете достичь этого, используя уравнение, и обрабатывать интерполяцию одновременно, если вы используете 3 вычисления синуса.

Это решает вашу проблему белого и черного и дает вам много цветового пространства. Если вам нужен абсолютно каждый пиксель цветового пространства, вам нужно выполнить горизонтальную интерполяцию по-другому, и вам потребуется 2 ^ 8 вместо 8 контрольных точек.

...