【问题标题】:Generate ordered colors programmatically以编程方式生成有序颜色
【发布时间】:2013-06-17 08:55:31
【问题描述】:

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

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

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];

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

【问题讨论】:

    标签: ios algorithm colors


    【解决方案1】:

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

    【讨论】:

    • 谢谢。我正在为此使用 Gimp。
    • 如您所见,任何内部颜色都有 26 种相邻颜色。也许您可以尝试一些 HSV 颜色的方法,然后将其转换为 RGB?
    【解决方案2】:

    我复制了 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;
    }
    

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-09-13
      • 2012-06-16
      • 1970-01-01
      • 2015-12-06
      • 2021-03-31
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多