1

如何以编程方式生成从一种颜色到另一种颜色的有序颜色范围?

如果我们有这个颜色范围,我们需要覆盖:

0    0    255  255  255
179  255  0    255  58
255  255  0    0    0

那些是蓝色,浅蓝色,绿色,黄色,橙红色。

到目前为止,我发现了一堆关于在 HSV 配色方案中生成随机颜色范围的问题。我需要有序的 RGB 和均匀分布的颜色范围。

我之前的解决方案是:

NSInteger input = (510.0f / 100.0f) * progressAmount;
input < 256 ? (_redColor = input) : (_redColor = 255);
input > 255 ? (_blueColor = 255 - (input - 255)) : (_blueColor = 255);
_indicatorColor = [UIColor colorWithRed:(CGFloat) _redColor / 255.0f green:0.0f blue:(CGFloat) _blueColor / 255.0f alpha:1.0f];

但现在我需要来自更复杂颜色范围的颜色。不像我有的只有三个。

4

2 回答 2

0

我从 CGGradient 复制了功能。编写此函数以从特定范围获取颜色。

// function:            get color depending on min and max range for progress control
// param progress:      current progress in progress range; eg. with range [-20, 60], progress can be any value in between
// param colors:        array of float values representing color RGBA components in [0, 255] range
// param locationRange: array of float values representing amount of color for two colors
// param numElements:   numer of colors and number of locations
// note:                min and max range can be a combination of positive and negative values: [-20, 50], [0, 100], [30, 90], [-60, -30]
+ (UIColor*) colorForProgress:(CGFloat)progress lowerRange:(CGFloat)lowerRange upperRange:(CGFloat)upperRange colorRGBAArray:(CGFloat*)colors locationRange:(CGFloat*)locationRange numElements:(NSUInteger)numElements
{
    NSAssert(colors != NULL, @"color array is NULL");
    NSAssert(locationRange != NULL, @"numElements is NULL");
#ifdef DEBUG
    for (int i = 0; i < numElements; i++)
    {
        NSAssert2(locationRange[i] >= 0.0f && locationRange[i] <= 1.0f, @"locationRange %d %6.2f not in range [0.0, 1.0]", i, locationRange[i]);
    }
#endif

    UIColor *resultColor;

    // convert user range to local range

    // normalize range to [0-n]
    CGFloat rangeNormalized = upperRange - lowerRange;
    NSLog(@"rangeNormalized: %6.2f", rangeNormalized);

    // normalize input to range [0, range_normalized_max]
    // r = progress - lowerRange
    CGFloat progressNormalized = progress - lowerRange;
    NSLog(@"progressNormalized: %6.2f", progressNormalized);

    // map normalized range to [0, 100] percent
    CGFloat progressPercent = (100.0f / rangeNormalized) * progressNormalized;
    NSLog(@"progressPercent: %6.2f", progressPercent);

    // map normalized progress to [0.0, 1.0]
    CGFloat progressLocal = progressPercent / 100.0f;
    NSLog(@"progress_01: %6.2f", progressLocal);
    NSAssert(progressLocal >= 0.0f && progressLocal <= 1.0f, @"progress_01 not in range [0.0, 1.0]");

    // find two colors for range_s
    CGFloat b1 = 0, b2 = 0, *color1 = NULL, *color2 = NULL;

    if (progressLocal < 1.0f)
    {
        for (int i = 0; i < numElements - 1; i++) // ingore last
        {
            if (progressLocal >= locationRange[i] && progressLocal < locationRange[i+1])
            {
                b1 = locationRange[i];
                b2 = locationRange[i+1];
                color1 = colors + (4 * i); // iterate colors
                color2 = colors + (4 * (i+1));
                break;
            }
        }
    } else if (progressLocal == 1.0f)
    {
        b1 = locationRange[numElements - 2];
        b2 = locationRange[numElements - 1];
        color1 = colors + (4 * (numElements - 2));
        color2 = colors + (4 * (numElements - 1));
    }
    NSLog(@"b1: %6.2f, b2: %6.2f", b1, b2);
    NSLog(@"color1: %6.2f, %6.2f, %6.2f, %6.2f", color1[0], color1[1], color1[2], color1[3]);
    NSLog(@"color2: %6.2f, %6.2f, %6.2f, %6.2f", color2[0], color2[1], color2[2], color2[3]);

    CGFloat localRange = b2 - b1;
    NSLog(@"localRange: %6.2f", localRange);

    CGFloat localAmount = progressLocal - b1;
    NSLog(@"localAmount: %6.2f", localAmount);

    // colors

    CGFloat newColors[4];

    // each color component in both colors
    for (int i = 0; i < 3; i++)
    {
        printf("\n");
        NSLog(@"color1[%d]: %6.2f", i, color1[i]);
        NSLog(@"color2[%d]: %6.2f", i, color2[i]);

        newColors[i] = color1[i];
        NSLog(@"newColors[%d]: %6.2f", i, newColors[i]);

        CGFloat color_range = color1[i] > color2[i] ? (color1[i] - color2[i]) : (color2[i] - color1[i]);
        NSLog(@"color_range: %6.2f", color_range);

        // color_range map localRange
        CGFloat incr = color_range / localRange;
        NSLog(@"incr: %6.2f", incr);

        CGFloat result = incr * localAmount;
        if (color1[i] > color2[i])
        {
            result = -result;
        }
        NSLog(@"result: %6.2f", result);

        newColors[i] += result;
        NSLog(@"newColors[%d]: %6.2f", i, newColors[i]);
    }

    resultColor = [UIColor colorWithRed:newColors[0] / 255.0f green:newColors[1] / 255.0f blue:newColors[2] / 255.0f alpha:1.0f];
    printUIColor(resultColor);

    return resultColor;
}

如果有人提出更好的解决方案,我会暂时不回答这个问题。

于 2013-06-17T14:05:59.650 回答
0

看看 rgb 空间的图像,您可能会找到一些解决方案,如何在所需颜色之间做出简单的方式。

在此处输入图像描述

于 2013-06-17T09:07:09.347 回答