跳到内容

颜色理论/颜色渐变

来自维基教科书,开放的书籍,开放的世界
“将计算阶段与着色阶段分开” - 克劳德·海兰德-艾伦
有趣颜色渐变的示例

颜色渐变类型

[编辑 | 编辑源代码]

颜色渐变可以根据以下方面命名 

这里像素的颜色与 1D 变量成比例。例如,在 2D 空间(复数平面,其中点 z = x+y*i) 

返回介于两个给定颜色之间的颜色的函数示例

 
colorA = [0, 0, 255] # blue
colorB = [255, 0, 0] # red
function get_gradient_color(val):
# 'val' must be between 0 and 1
for i in [1,2,3]:
color[i] = colorA[i] + val * (colorB[i] - colorA[i])
return color


代码


域着色 函数的绘图。
ƒ(x) =(x2 − 1)(x − 2 − i)2/(x2 + 2 + 2i)。色调代表函数参数,而饱和度代表幅度。

因为颜色可以被视为超过1D的值,所以它被用来表示超过一个(实数或1D)变量。例如

' panomand/src/dll/fbmandel.bas
' https://www.unilim.fr/pages_perso/jean.debord/panoramic/mandel/panoramic_mandel.htm
' PANOMAND is an open source software for plotting Mandelbrot and Julia sets. It is written in two BASIC dialects: PANORAMIC and FreeBASIC
' by Jean Debord
' a simplified version of R Munafo's algorithm
' Color is defined in HSV space, according to Robert Munafo 
' (http://mrob.com/pub/muency/color.html): the value V is 
' computed from the distance estimator, while the hue H and 
' saturation S are computed from the iteration number.

function MdbCol(byval Iter as integer, _
                byval mz   as double, _
                byref dz   as Complex) as integer
' Computes the color of a point
' Iter = iteration count
' mz   = modulus of z at iteration Iter
' dz   = derivative at iteration Iter

  if Iter = Max_Iter then return &HFFFFFF

  dim as double  lmz, mdz, Dist, Dwell, DScale, Angle, Radius, Q, H, S, V
  dim as integer R, G, B
  
  lmz = log(mz)
  mdz = CAbs(dz)
  
  ' Determine Value (luminosity) from Distance Estimator
  
  V = 1
  
  if mdz > 0 then
    Dist = pp * mz * lmz / mdz
    DScale = log(Dist / ScaleFact) / Lnp + Dist_Fact
    if DScale < -8 then
      V = 0
    elseif DScale < 0 then
      V = 1 + DScale / 8
    end if
  end if

  ' Determine Hue and Saturation from Continuous Dwell

  Dwell = Iter - log(lmz) / Lnp + LLE
  Q = log(abs(Dwell)) * AbsColor
  
  if Q < 0.5 then
    Q = 1 - 1.5 * Q
    Angle = 1 - Q
  else
    Q = 1.5 * Q - 0.5
    Angle = Q
  end if
  
  Radius = sqr(Q)
  
  if (Iter mod 2 = 1) and (Color_Fact > 0) then
    V = 0.85 * V
    Radius = 0.667 * Radius
  end if
  
  H = frac(Angle * 10)
  S = frac(Radius)
   
  HSVtoRGB H * 360, S, V, R, G, B
  return rgb(R, G, B)

end function
  • Hans Lundmark 页面 [13]

颜色模型

[编辑 | 编辑源代码]

颜色模型描述

16 位线性 RGB 的质量与 12 位 sRGB(= 非线性 RGB)大致相同,因为线性颜色会导致靠近白色区域的样本过多,而靠近黑色区域的样本过少。



类型  

  • RGB 用于显示
  • CMYK 用于印刷
  • 其他(HSV、HSL 等)用于选择颜色、处理
    • HSLuv
    • YUV(亮度和色度)是一种将图像中的亮度和颜色分解成数字的方法
    • HWB [14]
  • RGB = "线性" 颜色空间
  • sRGB
    • sRGB = 标准 RGB。SRGBColorSpace (“srgb”) 指的是由 Rec. 709 主色、D65 白点和非线性 sRGB 传输函数定义的颜色空间。
    • sRGB 线性空间与 sRGB 相同,只是传输函数为线性光(没有伽马编码)
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <complex.h> // http://pubs.opengroup.org/onlinepubs/009604499/basedefs/complex.h.html

/* 
based on 
c++ program from :
http://commons.wikimedia.org/wiki/File:Color_complex_plot.jpg
by  	Claudio Rocchini

gcc d.c -lm -Wall

http://en.wikipedia.org/wiki/Domain_coloring

*/
 
const double PI = 3.1415926535897932384626433832795;
const double E  = 2.7182818284590452353602874713527;

/*

complex domain coloring 
Given a complex number z=re^{ i \theta},

hue represents the argument ( phase, theta ),

sat and value represents the modulus

*/
int GiveHSV( double complex z, double HSVcolor[3] )
{
 //The HSV, or HSB, model describes colors in terms of hue, saturation, and value (brightness).
 
 // hue = f(argument(z))
 //hue values range from .. to ..
 double a = carg(z); //
 while(a<0) a += 2*PI; a /= 2*PI;

 // radius of z
 double m = cabs(z); // 
 double ranges = 0;
 double rangee = 1;
 while(m>rangee){
   ranges = rangee;
   rangee *= E;
      }
 double k = (m-ranges)/(rangee-ranges);

 // saturation = g(abs(z))
 double sat = k<0.5 ? k*2: 1 - (k-0.5)*2;
 sat = 1 - pow( (1-sat), 3); 
 sat = 0.4 + sat*0.6;

 // value = h(abs(z))
 double val = k<0.5 ? k*2: 1 - (k-0.5)*2; 
   val = 1 - val;
   val = 1 - pow( (1-val), 3); 
   val = 0.6 + val*0.4;
 
 HSVcolor[0]= a;
 HSVcolor[1]= sat;
 HSVcolor[2]= val;
return 0;
}
  
 
int GiveRGBfromHSV( double HSVcolor[3], unsigned char RGBcolor[3] ) {
        double r,g,b;
        double h; double s; double v;
        h=HSVcolor[0]; // hue 
        s=HSVcolor[1]; //  saturation;
        v = HSVcolor[2]; // = value;

        if(s==0)
                r = g = b = v;
        else {
                if(h==1) h = 0;
                double z = floor(h*6); 
                int i = (int)z;
                double f = (h*6 - z);
                double p = v*(1-s);
                double q = v*(1-s*f);
                double t = v*(1-s*(1-f));
                switch(i){
                        case 0: r=v; g=t; b=p; break;
                        case 1: r=q; g=v; b=p; break;
                        case 2: r=p; g=v; b=t; break;
                        case 3: r=p; g=q; b=v; break;
                        case 4: r=t; g=p; b=v; break;
                        case 5: r=v; g=p; b=q; break;
                }
        }
        int c;
        c = (int)(256*r); if(c>255) c = 255; RGBcolor[0] = c;
        c = (int)(256*g); if(c>255) c = 255; RGBcolor[1] = c;
        c = (int)(256*b); if(c>255) c = 255; RGBcolor[2] = c;
  return 0;
}

int GiveRGBColor( double complex z, unsigned char RGBcolor[3])
{
  static double HSVcolor[3];
  GiveHSV( z, HSVcolor );
  GiveRGBfromHSV(HSVcolor,RGBcolor);
  return 0;
}

//  
double complex fun(double complex c ){
  return (cpow(c,2)-1)*cpow(c-2.0- I,2)/(cpow(c,2)+2+2*I);} // 
 
int main(){
        // screen (integer ) coordinate
        const int dimx = 800; const int dimy = 800;
        // world ( double) coordinate
        const double reMin = -2; const double reMax =  2;
        const double imMin = -2; const double imMax =  2;
        // 
        double stepX=(imMax-imMin)/(dimy-1);
        double stepY=(reMax-reMin)/(dimx-1);
        
        static unsigned char RGBcolor[3];
        FILE * fp;
        char *filename ="complex.ppm";
        fp = fopen(filename,"wb");
        fprintf(fp,"P6\n%d %d\n255\n",dimx,dimy);

        int i,j;
        for(j=0;j<dimy;++j){
                double im = imMax - j*stepX;
                for(i=0;i<dimx;++i){            
                        double re = reMax - i*stepY;
                        double complex z= re + im*I; // 
                        double complex v = fun(z); //     
                        GiveRGBColor( v, RGBcolor);
                        
                        fwrite(RGBcolor,1,3,fp);
                }
        }
        fclose(fp);
        printf("OK - file %s saved\n", filename);

        return 0;
}

在 Basic 中  

' /panomand/src/dll/hsvtorgb.bas
' https://www.unilim.fr/pages_perso/jean.debord/panoramic/mandel/panoramic_mandel.htm
' PANOMAND is an open source software for plotting Mandelbrot and Julia sets. It is written in two BASIC dialects: PANORAMIC and FreeBASIC
' by Jean Debord
sub HSVtoRGB(byref H as double,  _
             byref S as double,  _
             byref V as double,  _
             byref R as integer, _
             byref G as integer, _
             byref B as integer)

' Convert RGB to HSV
' Adapted from http://www.cs.rit.edu/~ncs/color/t_convert.html
' R, G, B values are from 0 to 255
' H = [0..360], S = [0..1], V = [0..1]
' if S = 0, then H = -1 (undefined)

  if S = 0 then  ' achromatic (grey)
    R = V * 255
    G = R
    B = R
    exit sub
  end if

  dim as integer I
  dim as double  Z, F, P, Q, T
  dim as double  RR, GG, BB
  
  Z = H / 60     ' sector 0 to 5
  I = int(Z)
  F = frac(Z)
  P = V * (1 - S)
  Q = V * (1 - S * F)
  T = V * (1 - S * (1 - F))

  select case I
    case 0
      RR = V
      GG = T
      BB = P
    case 1
      RR = Q
      GG = V
      BB = P
    case 2
      RR = P
      GG = V
      BB = T
    case 3
      RR = P
      GG = Q
      BB = V
    case 4
      RR = T
      GG = P
      BB = V
    case 5
      RR = V
      GG = P
      BB = Q
  end select

  R = RR * 255
  G = GG * 255
  B = BB * 255
end sub

插值函数

[编辑 | 编辑源代码]
  • 可以在梯度的每个段中使用任何函数。
  • 函数的输出被缩放到颜色分量的范围。
  • 插值 颜色之间可以是
    • lerp = 线性插值,在 sRGB 颜色空间中
    • 非线性(二次方等),Photoshop 中的经典方法 [15]
    • 线性颜色空间插值:将键从 sRGB 转换为浮点数线性,在它们之间进行 lerp,再转换回定点 sRGB
    • 感知颜色空间插值(OKlab):将键从 sRGB 转换为浮点数线性,再转换为 Oklab,在它们之间进行 lerp,再转换回浮点数线性,再转换回定点 sRGB。[16]


Aras Pranckevičius 编写的 Oklab 评估函数代码的尾部

// to-Linear -> to-Oklab -> lerp -> to-Linear -> to-sRGB
float3 ca = pix_to_float(m_Keys[idx]);
float3 cb = pix_to_float(m_Keys[idx+1]);
ca = sRGB_to_Linear(ca);
cb = sRGB_to_Linear(cb);
ca = Linear_sRGB_to_OkLab_Ref(ca);
cb = Linear_sRGB_to_OkLab_Ref(cb);
float3 c = lerp(ca, cb, a);
c = OkLab_to_Linear_sRGB_Ref(c);
c = Linear_to_sRGB(c);
return float_to_pix(c);


在 CSS 中,两个颜色值之间的插值 是通过执行以下步骤完成的:[17]

  • (如果需要)将它们转换为给定的颜色空间,在下文中称为插值颜色空间。
  • (如果需要)在转换后的颜色中重新插入已传递的值。
  • (如果需要)根据所选的 <hue-interpolation-method> 调整色调。
  • 颜色分量的预乘。
  • 对颜色计算值的每个分量进行线性插值。
  • 撤销预乘。

示例 36。要插值:[18]

  • 在 Lab 颜色空间中
  • 两种颜色:rgb(76% 62% 03%/0.4) 和 color(display-p3 0.84 0.19 0.72/0.6)
  • 它们首先转换为 lab:lab(66.927% 4.873 68.622/0.4) lab(53.503% 82.672 -33.901/0.6)
  • 预乘:然后在插值之前对 L、a 和 b 坐标进行预乘:[26.771% 1.949 27.449] 和 [32.102% 49.603 -20.341]。
  • 插值:对这些进行线性插值的中间点将是 [29.4365% 25.776 3.554],
  • 撤销预乘:具有 0.5 的 alpha 值,得到 lab(58.873% 51.552 7.108) / 0.5)。

颜色数量

[编辑 | 编辑源代码]

颜色的数量由 颜色深度 决定:从 2 种颜色到 1600 万种颜色。

另请参阅

重复和偏移

[编辑 | 编辑源代码]

直接重复  

颜色与颜色在颜色渐变中的位置 <0;1> 成正比。如果位置 > 1,则会有颜色重复。这可能很有用

镜像重复  

"colorCycleMirror - 这将反映颜色渐变,使其平滑循环" [19]

偏移  

如何在计算机程序中使用颜色渐变

[编辑 | 编辑源代码]
调色板图形、调色板替换机制

首先找到程序中所需的颜色格式。[20][21]

创建渐变的方法  

  • 渐变函数
  • 渐变文件
    • 颜色查找表 (CLUT)[22]) 颜色映射、调色板
    • 调色板 [23][24]
    • 混合 [25]


  "Lookup tables (LUTs) are an excellent technique for optimizing the evaluation of functions that are expensive to compute and inexpensive to cache. ... For data requests that fall between the table's samples, an interpolation algorithm can generate reasonable approximations by averaging nearby samples."[26]

CLUT 图像

[编辑 | 编辑源代码]

可以使用 CLUT 图像作为渐变的来源 [27][28]

  convert input.pgm -level 0,65532 clut.ppm -interpolate integer -clut -depth 8 output.png

CLUT 数组

[编辑 | 编辑源代码]
# http://jtauber.com/blog/2008/05/18/creating_gradients_programmatically_in_python/
# Creating Gradients Programmatically in Python by James Tauber

import sys

def write_png(filename, width, height, rgb_func):
    
    import zlib
    import struct
    import array
    
    def output_chunk(out, chunk_type, data):
        out.write(struct.pack("!I", len(data)))
        out.write(chunk_type)
        out.write(data)
        checksum = zlib.crc32(data, zlib.crc32(chunk_type))
        out.write(struct.pack("!I", checksum))
    
    def get_data(width, height, rgb_func):
        fw = float(width)
        fh = float(height)
        compressor = zlib.compressobj()
        data = array.array("B")
        for y in range(height):
            data.append(0)
            fy = float(y)
            for x in range(width):
                fx = float(x)
                data.extend([int(v * 255) for v in rgb_func(fx / fw, fy / fh)])
        compressed = compressor.compress(data.tostring())
        flushed = compressor.flush()
        return compressed + flushed
    
    out = open(filename, "w")
    out.write(struct.pack("8B", 137, 80, 78, 71, 13, 10, 26, 10))
    output_chunk(out, "IHDR", struct.pack("!2I5B", width, height, 8, 2, 0, 0, 0))
    output_chunk(out, "IDAT", get_data(width, height, rgb_func))
    output_chunk(out, "IEND", "")
    out.close()

def linear_gradient(start_value, stop_value, start_offset=0.0, stop_offset=1.0):
    return lambda offset: (start_value + ((offset - start_offset) / (stop_offset - start_offset) * (stop_value - start_value))) / 255.0

def gradient(DATA):
    def gradient_function(x, y):
        initial_offset = 0.0
        for offset, start, end in DATA:
            if y < offset:
                r = linear_gradient(start[0], end[0], initial_offset, offset)(y)
                g = linear_gradient(start[1], end[1], initial_offset, offset)(y)
                b = linear_gradient(start[2], end[2], initial_offset, offset)(y)
                return r, g, b
            initial_offset = offset
    return gradient_function

## EXAMPLES

# normally you would make these with width=1 but below I've made them 50
# so you can more easily see the result

# body background from jtauber.com and quisition.com
write_png("test1.png", 50, 143, gradient([
    (1.0, (0xA1, 0xA1, 0xA1), (0xDF, 0xDF, 0xDF)),
]))

# header background similar to that on jtauber.com
write_png("test2.png", 50, 90, gradient([
    (0.43, (0xBF, 0x94, 0xC0), (0x4C, 0x26, 0x4C)), # top
    (0.85, (0x4C, 0x26, 0x4C), (0x27, 0x13, 0x27)), # bottom
    (1.0,  (0x66, 0x66, 0x66), (0xFF, 0xFF, 0xFF)), # shadow
]))

# header background from pinax
write_png("test3.png", 50, 80, gradient([
    (0.72, (0x00, 0x26, 0x4D), (0x00, 0x40, 0x80)),
    (1.0,  (0x00, 0x40, 0x80), (0x00, 0x6C, 0xCF)), # glow
]))

# form input background from pinax
write_png("test4.png", 50, 25, gradient([
    (0.33, (0xDD, 0xDD, 0xDD), (0xF3, 0xF3, 0xF3)), # top-shadow
    (1.0,  (0xF3, 0xF3, 0xF3), (0xF3, 0xF3, 0xF3)),
]))
# Perl code
# http://www.angelfire.com/d20/roll_d3_for_this/mandel-highorder/mandel-high.pl
# from perl High-order Mandelbrot program.
# Written by Christopher Thomas.
# Picture palette info.

my ($palsize);
my (@palette);

if(0)
{
# Light/dark colour banded palette.
# NOTE: This looks ugly, probably because the dark colours look muddy.
$palsize = 16;
@palette =
  ( "  255   0   0", "    0 112 112", "  255 128   0", "    0   0 128",
    "  224 224   0", "   64   0  96", "    0 255   0", "   96   0  64",
    "    0 224 224", "  128   0   0", "    0   0 255", "  128  64   0",
    "  128   0 192", "  112 112   0", "  192   0 128", "    0 128   0" );
}
else
{
# 8-colour rainbow palette.
$palsize = 8;
@palette =
  ( "  255   0   0", "  255 128   0",
    "  224 224   0", "    0 255   0",
    "    0 224 224", "    0   0 255",
    "  128   0 192", "  192   0 128" );
}

转换  

  • 在 FractInt 和 Fractal eXtreme 调色板之间 [29]

列表

渐变函数

[编辑 | 编辑源代码]

名称

  • 着色函数

类型

gnuplot 中颜色调色板的 RGB 配置文件

示例 

// https://www.shadertoy.com/view/lsd3zN
// sRGB demo by Tom Forsyth
// https://medium.com/@tomforsyth/the-srgb-learning-curve-773b7f68cf7a
//////////////////////////////////////////////////////////
//
// Illustration of the precision distribution of linear
// and sRGB formats.
//
// A ramp of 64 shades of each colour is shown to
// emphasise the distribution of banding in each format.
// Real formats of course have 256 shades.
// 
// The leftmost bar of each colour is a linear format
// As you can see, although this format is linear in
// "photons per second", the difference in shades between
// the darker bands is far more obvious to the eye than
// the difference between the brighter bands. Thus,
// although linear space is a good place to do maths,
// when stored in a buffer the distribution of precision
// is poorly matched to the eye's preception of brightness.
//
// The middle bar of each colour is an sRGB format.
// While this is a strange non-linear format, and doing
// maths in it is not a good idea, it is an excellent
// format for storing "picturelike" data. You can see
// that the change in perceived brightness between adjacent
// bands is very uniform across the entire range of
// brightnesses, meaning that it has a distribution of
// precision that matches the eye's perception very well.
//
// The rightmost bar of each colour is a gamma 2.2 bar.
// This is not directly supported by hardware, and is there
// to illustrate that although it is quite similar to sRGB,
// there are significant differences between them, and
// care must be taken if trying to approximate one with
// the other. In general, it's not worth the very small
// performance difference.
//
//////////////////////////////////////////////////////////


// Taken from D3DX_DXGIFormatConvert.inl
float D3DX_FLOAT_to_SRGB ( float val )
{
	if( val < 0.0031308 )
		val *= 12.92;
	else
		val = 1.055 * pow(val,1.0/2.4) - 0.055;
	return val;
}

// Taken from D3DX_DXGIFormatConvert.inl
// Technically this is not bit-exact - that requires a look-up table,
// but it's accurate enough for our purposes here.
float D3DX_SRGB_to_FLOAT(float val)
{
    if( val < 0.04045 )
        val /= 12.92;
    else
        val = pow((val + 0.055)/1.055,2.4);
    return val;
}

void mainImage( out vec4 fragColor, in vec2 fragCoord )
{
	vec2 uv = fragCoord.xy / iResolution.xy;

    float yShade = uv.y;

    int colCol = int(floor(uv.x*4.0));
	float fraction = uv.x*4.0 - float(colCol);
    int colRamp = int(floor(fraction * 3.1));
       
    // Make the basic colour.
    vec3 baseCol;
    if ( colCol == 0 )
    {
        baseCol = vec3(yShade,yShade,yShade); // white
    }
    else if ( colCol == 1 )
    {
        baseCol = vec3(yShade*0.6,yShade,0.0); // light green
    }
    else if ( colCol == 2 )
    {
        baseCol = vec3(yShade,yShade*0.5,yShade*0.2); // bronzeish
    }
    else
    {
        baseCol = vec3(yShade*0.5,0.0,yShade); // purple
    }
    
    
    // Artificially quantise to emphasise precision distribution
    float shadeSteps = 64.0;
    baseCol = (1.0/shadeSteps) * floor ( baseCol * shadeSteps );
    
    // Now interpret that value as if it was a value stored in a texture of various formats.
    
    vec3 linearCol;
    if ( colRamp == 0 )
    {
        // Linear texture
        linearCol = baseCol;
    }
    else if ( colRamp == 1 )
    {
        // sRGB texture
        linearCol.x = D3DX_SRGB_to_FLOAT ( baseCol.x );
        linearCol.y = D3DX_SRGB_to_FLOAT ( baseCol.y );
        linearCol.z = D3DX_SRGB_to_FLOAT ( baseCol.z );
    }
    else if ( colRamp == 2 )
    {
        // 2.2 gamma for illustration
        linearCol.x = pow ( baseCol.x, 2.2 );
        linearCol.y = pow ( baseCol.y, 2.2 );
        linearCol.z = pow ( baseCol.z, 2.2 );
    }
    else
    {
        // Separator.
        linearCol = vec3(0.0,0.0,0.0);
    }
    
    
    // But then assume the display we're outputting to is gamma 2.2
    float displayGamma = 2.2;
    fragColor.x = pow ( linearCol.x, 1.0/displayGamma );
    fragColor.y = pow ( linearCol.y, 1.0/displayGamma );
    fragColor.z = pow ( linearCol.z, 1.0/displayGamma );
    fragColor.w = 1.0;
}

HSV 渐变

[编辑 | 编辑源代码]
  • Robert P. Munafo 的解释[41]
  • Jean Debord 的基本代码和图像[42]
  • Curtis T McMullen 编写的 c 程序 [43]

具有 6 个片段的线性 RGB 渐变

[编辑 | 编辑源代码]


彩虹渐变


这里的渐变由 6 个片段组成。在每个片段中,仅使用线性函数更改颜色的一个 RGB 分量。

Delphi 版本

[编辑 | 编辑源代码]
// Delphi version by Witold J.Janik with help Andrzeja Wąsika from [pl.comp.lang.delphi]
//  [i] changes from [iMin] to [iMax]

function GiveRainbowColor(iMin, iMax, i: Integer): TColor;
var 
  m: Double;
  r, g, b, mt: Byte;
begin
  m := (i - iMin)/(iMax - iMin + 1) * 6;
  mt := (round(frac(m)*$FF));
  case Trunc(m) of
  0: begin
      R := $FF;
      G := mt;
      B := 0;
    end;
  1: begin
      R := $FF - mt;
      G := $FF;
      B := 0;
    end;
  2: begin
      R := 0;
      G := $FF;
      B := mt;
    end;
  3: begin
      R := 0;
      G := $FF - mt;
      B := $FF;
    end;
  4: begin
      R := mt;
      G := 0;
      B := $FF;
    end;
  5: begin
      R := $FF;
      G := 0;
      B := $FF - mt;
    end;
end; // case

  Result := rgb(R,G,B);
end; 
/////

函数的输入是 2 个变量 

  • 渐变中颜色的位置,(0.0 到 1.0 之间的归一化浮点数)
  • 颜色作为 RGB 分量的数组(无符号整数,从 0 到 255)

此函数不使用直接输出(void),而是更改输入变量颜色。可以用这种方式使用它


GiveRainbowColor(0.25,color);
/* based on Delphi function by Witold J.Janik */
void GiveRainbowColor(double position,unsigned char c[])
{
  /* if position > 1 then we have repetition of colors it maybe useful    */
      
  if (position>1.0){if (position-(int)position==0.0)position=1.0; else position=position-(int)position;}
  
  
 
  
  unsigned char nmax=6; /* number of color segments */
  double m=nmax* position;
  
  int n=(int)m; // integer of m
  
  double f=m-n;  // fraction of m
  unsigned char t=(int)(f*255);

  
switch( n){
   case 0: {
      c[0] = 255;
      c[1] = t;
      c[2] = 0;
       break;
    };
   case 1: {
      c[0] = 255 - t;
      c[1] = 255;
      c[2] = 0;
       break;
    };
   case 2: {
      c[0] = 0;
      c[1] = 255;
      c[2] = t;
       break;
    };
   case 3: {
      c[0] = 0;
      c[1] = 255 - t;
      c[2] = 255;
       break;
    };
   case 4: {
      c[0] = t;
      c[1] = 0;
      c[2] = 255;
       break;
    };
   case 5: {
      c[0] = 255;
      c[1] = 0;
      c[2] = 255 - t;
       break;
    };
    default: {
      c[0] = 255;
      c[1] = 0;
      c[2] = 0;
       break;
    };

}; // case
}

Cpp 版本

[编辑 | 编辑源代码]
// C++ version
// here are some my modification but the main code is the same 
// as in Witold J.Janik code
//

Uint32 GiveRainbowColor(double position)

// this function gives 1D linear RGB color gradient 
// color is proportional to position 
// position  <0;1> 
// position means position of color in color gradient

{
  if (position>1)position=position-int(position);
  // if position > 1 then we have repetition of colors
  // it maybe useful
  Uint8 R, G, B;// byte
  int nmax=6;// number of color bars
  double m=nmax* position;
  int n=int(m); // integer of m
  double f=m-n;  // fraction of m
  Uint8 t=int(f*255);
  
  
switch( n){
   case 0: {
      R = 255;
      G = t;
      B = 0;
       break;
    };
   case 1: {
      R = 255 - t;
      G = 255;
      B = 0;
       break;
    };
   case 2: {
      R = 0;
      G = 255;
      B = t;
       break;
    };
   case 3: {
      R = 0;
      G = 255 - t;
      B = 255;
       break;
    };
   case 4: {
      R = t;
      G = 0;
      B = 255;
       break;
    };
   case 5: {
      R = 255;
      G = 0;
      B = 255 - t;
       break;
    };

}; // case

  return (R << 16) | (G << 8) | B;
}

基于正弦的渐变

[编辑 | 编辑源代码]


"想法是根据正弦波改变颜色。这会产生一种不错的平滑渐变效果(虽然它不是线性的,但这并非要求)。通过更改 RGB 分量的频率(理论上我们可以使用其他颜色空间,例如 HSV),我们可以获得各种渐变。此外,我们还可以玩转每个颜色分量的相位,从而产生“移位”效果。这种渐变的基本实现可以这样实现:"

/* 
http://blogs.microsoft.co.il/pavely/2013/11/12/color-gradient-generator/


*/
public Color[] GenerateColors(int number) {
    var colors = new List<Color>(number);
    double step = MaxAngle / number;
    for(int i = 0; i < number; ++i) {
        var r = (Math.Sin(FreqRed * i * step + PhaseRed) + 1) * .5;
        var g = (Math.Sin(FreqGreen * i * step + PhaseGreen) + 1) * .5;
        var b = (Math.Sin(FreqBlue * i * step + PhaseBlue) + 1) * .5;
        colors.Add(Color.FromRgb((byte)(r * 255), (byte)(g * 255), (byte)(b * 255)));
    }
    return colors.ToArray();
}

"其中

  • Freq* 是各个 RGB 颜色的频率
  • Phase* 是相移值。

请注意,所有计算都是使用浮点数(范围为 0.0 到 1.0)完成的,最后转换为 WPF 颜色结构(在本例中)。这仅仅是因为方便,因为我们使用的是三角函数,它喜欢浮点数而不是整数。结果被归一化为 0 到 1 的范围,因为正弦函数产生的结果从 –1 到 1,因此我们加 1 以获得 0 到 2 的范围,最后除以 2 以获得所需的范围。"[44]


cubehelix

[编辑 | 编辑源代码]

cubehelix 渐变

/* 
 GNUPLOT - stdfn.h 
 Copyright 1986 - 1993, 1998, 2004   Thomas Williams, Colin Kelley 
*/
#ifndef clip_to_01
#define clip_to_01(val)	\
    ((val) < 0 ? 0 : (val) > 1 ? 1 : (val))
#endif

/*
 input : position
 output : c array ( rgb color)
 
the colour scheme spirals (as a squashed helix) around the diagonal of the RGB colour cube 

https://arxiv.org/abs/1108.5083
A colour scheme for the display of astronomical intensity images by D. A. Green 
*/
void GiveCubehelixColor(double position, unsigned char c[]){



	/* GNUPLOT - color.h 
	 * Petr Mikulik, December 1998 -- June 1999
	 * Copyright: open source as much as possible
	*/

	// t_sm_palette 
  	/* gamma for gray scale and cubehelix palettes only */
  	double gamma = 1.5;

  	/* control parameters for the cubehelix palette scheme */
  	//set palette cubehelix start 0.5 cycles -1.5 saturation 1
	//set palette gamma 1.5
  	double cubehelix_start = 0.5;	/* offset (radians) from colorwheel 0 */
  	double cubehelix_cycles = -1.5;	/* number of times round the colorwheel */
  	double cubehelix_saturation = 1.0;	/* color saturation */
	double r,g,b;
	double gray = position; 
 


	
	/*
 	 Petr Mikulik, December 1998 -- June 1999
 	* Copyright: open source as much as possible
 	*/
	// /* Map gray in [0,1] to color components according to colorMode */
	// function color_components_from_gray
	// from gnuplot/src/getcolor.c
	double phi, a;
	
	phi = 2. * M_PI * (cubehelix_start/3. +  gray * cubehelix_cycles);
	
	// gamma correction
	if (gamma != 1.0)    gray = pow(gray, 1./gamma);
	
	
	a = cubehelix_saturation * gray * (1.-gray) / 2.;
	
	// compute
	r = gray + a * (-0.14861 * cos(phi) + 1.78277 * sin(phi));
	g = gray + a * (-0.29227 * cos(phi) - 0.90649 * sin(phi));
	b = gray + a * ( 1.97294 * cos(phi));
	
	// normalize to [9,1] range
	r = clip_to_01(r);
	g = clip_to_01(g);
	b = clip_to_01(b);
	
	// change range to [0,255]
  	c[0] = (unsigned char) 255*r; //R
  	c[1] = (unsigned char) 255*g; // G
  	c[2] = (unsigned char) 255*b; // B	

}

渐变文件

[编辑 | 编辑源代码]
  • 颜色查找表 (CLUT)

颜色渐变的文件类型

[编辑 | 编辑源代码]

颜色渐变有特殊的文件类型:[45][46]

  • GIMP 使用扩展名为 .ggr 的文件[47]
  • Fractint 使用 .map 文件 [48]
  • UltraFractal 使用 .ugr - 这些文件可以包含多个渐变
  • ual - 旧的 Ultra Fractal 渐变文件
  • rgb, pal, gpf - gnuplot 文件
  • Matplotlib[49] 颜色映射[50] 是一个查找表[51]
  • csv 文件
  • Paul Bourke 编写的 WHIP 格式 (Autodesk) 地图
  • Gnofract4D 仅在图形文件内部保存渐变,而不是作为单独文件。[52]
  • MatLab
  • Python
  • R
  • GMT
  • QGIS
  • Ncview
  • Ferret
  • Plotly
  • Paraview
  • VisIt
  • Mathematica
  • Surfer
  • d3
  • SKUA-GOCAD
  • Petrel
  • Fledermaus
  • Qimera
  • ImageJ
  • Fiji
  • Inkscape
  • XML
  • 文本
  • SASS 样式表
  • LESS - https://lesscss.org.cn 样式表
  • CSS - 层叠样式表

csv 文件

[编辑 | 编辑源代码]

Kenneth Moreland 编写的包含 33 个值的表格(存储在 csv 文件中)[53]

Scalar	R	G	B
0	59	76	192
0.03125	68	90	204
0.0625	77	104	215
0.09375	87	117	225
0.125	98	130	234
0.15625	108	142	241
0.1875	119	154	247
0.21875	130	165	251
0.25	141	176	254
0.28125	152	185	255
0.3125	163	194	255
0.34375	174	201	253
0.375	184	208	249
0.40625	194	213	244
0.4375	204	217	238
0.46875	213	219	230
0.5	221	221	221
0.53125	229	216	209
0.5625	236	211	197
0.59375	241	204	185
0.625	245	196	173
0.65625	247	187	160
0.6875	247	177	148
0.71875	247	166	135
0.75	244	154	123
0.78125	241	141	111
0.8125	236	127	99
0.84375	229	112	88
0.875	222	96	77
0.90625	213	80	66
0.9375	203	62	56
0.96875	192	40	47
1	180	4	38

CSS 语法

[编辑 | 编辑源代码]

CSS 语法[54][55]

CSS 中混合(和渐变)的默认颜色空间是 oklab


线性渐变
[编辑 | 编辑源代码]
不重复
[编辑 | 编辑源代码]

颜色渐变[56]

Css 代码 描述 预览图像
linear-gradient(in lab to right, white, #01E)
CIE Lab 渐变,它避免了过暗的中点,但具有明显的紫色色调;
linear-gradient(in srgb to right, white, #01E)
gamma 编码的 sRGB 渐变,在中点过暗,有点不饱和,并带有一点紫色色调
linear-gradient(in Oklab to right, white, #01E)
Oklab 渐变,提供更感知均匀的结果,完全没有紫色色调
linear-gradient(to right, #a8c0ff, #3f2b96);
海景
linear-gradient(in Oklab to right, #44C, #795)
Oklab 渐变,感知上均匀的结果,完全没有紫色色调
linear-gradient(in Oklab to right,  black, #01E)
Oklab 渐变,感知上均匀的结果
 linear-gradient(cyan, yellow);
 linear-gradient(to left, violet, indigo, blue, green, yellow, orange, red);
VIBGYOR 彩虹
 linear-gradient(90deg, rgba(2,0,36,1) 0%, rgba(9,9,121,1) 35%, rgba(0,212,255,1) 100%);


每个空间中的黑色到白色渐变[57]


描述 预览图像
Oklab,感知上均匀的结果
oklch
lab
lch
srgb
srgb-linear
hsl
hwb
xyz
xyz-d50
xyz-d65
重复
[edit | edit source]
代码 预览
.gradient5 {
  background-image: repeating-linear-gradient(cyan 0%, yellow 50%);
}
.gradient6 {
  background-image: repeating-linear-gradient(to right, blue 0%, magenta 10%);
}
.gradient7 {
  background-image: repeating-linear-gradient(60deg, cyan 0%, teal 23%, lime 31%);
}


圆锥形
[edit | edit source]

CSS 中的圆锥形渐变

/* 色相环 */ background: conic-gradient(red, yellow, lime, aqua, blue, magenta, red); border-radius: 50%

Css 代码 描述 预览图像
 conic-gradient(red, yellow, lime, aqua, blue, magenta, red); border-radius: 50%
色相环

Fractint 地图文件

[edit | edit source]

颜色映射文件的默认文件类型扩展名为“.MAP”。这些是 ASCII 文本文件。由一系列 RGB 三元组值组成(每行一个三元组,编码为颜色的红色、绿色和蓝色 [RGB] 分量)。颜色映射(或调色板)用作颜色查找表[58] 默认颜色映射位于 Default.map 文件中

0 0 0            The default VGA color map
0 0 168
0 168 0
0 168 168
168 0 0
168 0 168
168 84 0
168 168 168
84 84 84
84 84 252
84 252 84
84 252 252
252 84 84
252 84 252
252 252 84
252 252 252
0 0 0
20 20 20
32 32 32
44 44 44
56 56 56
68 68 68
80 80 80
96 96 96
112 112 112
128 128 128
144 144 144
160 160 160
180 180 180
200 200 200
224 224 224
252 252 252
0 0 252
64 0 252
124 0 252
188 0 252
252 0 252
252 0 188
252 0 124
252 0 64
252 0 0
252 64 0
252 124 0
252 188 0
252 252 0
188 252 0
124 252 0
64 252 0
0 252 0
0 252 64
0 252 124
0 252 188
0 252 252
0 188 252
0 124 252
0 64 252
124 124 252
156 124 252
188 124 252
220 124 252
252 124 252
252 124 220
252 124 188
252 124 156
252 124 124
252 156 124
252 188 124
252 220 124
252 252 124
220 252 124
188 252 124
156 252 124
124 252 124
124 252 156
124 252 188
124 252 220
124 252 252
124 220 252
124 188 252
124 156 252
180 180 252
196 180 252
216 180 252
232 180 252
252 180 252
252 180 232
252 180 216
252 180 196
252 180 180
252 196 180
252 216 180
252 232 180
252 252 180
232 252 180
216 252 180
196 252 180
180 252 180
180 252 196
180 252 216
180 252 232
180 252 252
180 232 252
180 216 252
180 196 252
0 0 112
28 0 112
56 0 112
84 0 112
112 0 112
112 0 84
112 0 56
112 0 28
112 0 0
112 28 0
112 56 0
112 84 0
112 112 0
84 112 0
56 112 0
28 112 0
0 112 0
0 112 28
0 112 56
0 112 84
0 112 112
0 84 112
0 56 112
0 28 112
56 56 112
68 56 112
84 56 112
96 56 112
112 56 112
112 56 96
112 56 84
112 56 68
112 56 56
112 68 56
112 84 56
112 96 56
112 112 56
96 112 56
84 112 56
68 112 56
56 112 56
56 112 68
56 112 84
56 112 96
56 112 112
56 96 112
56 84 112
56 68 112
80 80 112
88 80 112
96 80 112
104 80 112
112 80 112
112 80 104
112 80 96
112 80 88
112 80 80
112 88 80
112 96 80
112 104 80
112 112 80
104 112 80
96 112 80
88 112 80
80 112 80
80 112 88
80 112 96
80 112 104
80 112 112
80 104 112
80 96 112
80 88 112
0 0 64
16 0 64
32 0 64
48 0 64
64 0 64
64 0 48
64 0 32
64 0 16
64 0 0
64 16 0
64 32 0
64 48 0
64 64 0
48 64 0
32 64 0
16 64 0
0 64 0
0 64 16
0 64 32
0 64 48
0 64 64
0 48 64
0 32 64
0 16 64
32 32 64
40 32 64
48 32 64
56 32 64
64 32 64
64 32 56
64 32 48
64 32 40
64 32 32
64 40 32
64 48 32
64 56 32
64 64 32
56 64 32
48 64 32
40 64 32
32 64 32
32 64 40
32 64 48
32 64 56
32 64 64
32 56 64
32 48 64
32 40 64
44 44 64
48 44 64
52 44 64
60 44 64
64 44 64
64 44 60
64 44 52
64 44 48
64 44 44
64 48 44
64 52 44
64 60 44
64 64 44
60 64 44
52 64 44
48 64 44
44 64 44
44 64 48
44 64 52
44 64 60
44 64 64
44 60 64
44 52 64
44 48 64
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0
0 0 0

Gimp/Inscape gpl 文件

[edit | edit source]

使用于:Gimp、Inscape、Aseprite、Drawpile、Krita、MyPaint[59]


语法

  • ASCII 文件(文本文件)[60]
  • 注释必须以 # 开头。在非空行中,如果行首不是 #,则前三个标记将被解析为数字
  • 不支持 alpha
  • GIMP 调色板 - 它必须是文件的第一行[61]
  • Name: <name> - 设置颜色调色板的名称。
  • Columns: <number> - 只是一个在 GIMP 内部显示调色板的指示。
  • # <comment> - 注释必须以 # 开头。所有注释都被 GIMP 忽略。
  • 0 0 0 Black - 颜色的 RGB 值,后面是颜色名称


加载器函数的源代码 [62]

GIMP 调色板使用特殊的文件格式存储,存储在扩展名为 .gpl 的文件中。

目录

  • ~/.config/GIMP/x.y/palettes/ 目录(其中 x.y 是 GIMP 版本号)
  • ~/.config/inkscape/palettes/
GIMP Palette
Name: Material Design
Columns: 14
#
255 248 225		amber 50
255 236 179		amber 100
255 224 130		amber 200
255 213  79		amber 300
255 202  40		amber 400
255 193   7		amber 500
255 179   0		amber 600
255 160   0		amber 700
255 143   0		amber 800
255 111   0		amber 900
255 229 127		amber a100
255 215  64		amber a200
255 196   0		amber a400
255 171   0		amber a700
227 242 253		blue 50
187 222 251		blue 100
144 202 249		blue 200
100 181 246		blue 300
 66 165 245		blue 400
 33 150 243		blue 500
 30 136 229		blue 600
 25 118 210		blue 700
 21 101 192		blue 800
 13  71 161		blue 900
130 177 255		blue a100
 68 138 255		blue a200
 41 121 255		blue a400
 41  98 255		blue a700
224 247 250		cyan 50
178 235 242		cyan 100
128 222 234		cyan 200
 77 208 225		cyan 300
 38 198 218		cyan 400
  0 188 212		cyan 500
  0 172 193		cyan 600
  0 151 167		cyan 700
  0 131 143		cyan 800
  0  96 100		cyan 900
132 255 255		cyan a100
 24 255 255		cyan a200
  0 229 255		cyan a400
  0 184 212		cyan a700
251 233 231		deep-orange 50
255 204 188		deep-orange 100
255 171 145		deep-orange 200
255 138 101		deep-orange 300
255 112  67		deep-orange 400
255  87  34		deep-orange 500
244  81  30		deep-orange 600
230  74  25		deep-orange 700
216  67  21		deep-orange 800
191  54  12		deep-orange 900
255 158 128		deep-orange a100
255 110  64		deep-orange a200
255  61   0		deep-orange a400
221  44   0		deep-orange a700
237 231 246		deep-purple 50
209 196 233		deep-purple 100
179 157 219		deep-purple 200
149 117 205		deep-purple 300
126  87 194		deep-purple 400
103  58 183		deep-purple 500
 94  53 177		deep-purple 600
 81  45 168		deep-purple 700
 69  39 160		deep-purple 800
 49  27 146		deep-purple 900
179 136 255		deep-purple a100
124  77 255		deep-purple a200
101  31 255		deep-purple a400
 98   0 234		deep-purple a700
232 245 233		green 50
200 230 201		green 100
165 214 167		green 200
129 199 132		green 300
102 187 106		green 400
 76 175  80		green 500
 67 160  71		green 600
 56 142  60		green 700
 46 125  50		green 800
 27  94  32		green 900
185 246 202		green a100
105 240 174		green a200
  0 230 118		green a400
  0 200  83		green a700
232 234 246		indigo 50
197 202 233		indigo 100
159 168 218		indigo 200
121 134 203		indigo 300
 92 107 192		indigo 400
 63  81 181		indigo 500
 57  73 171		indigo 600
 48  63 159		indigo 700
 40  53 147		indigo 800
 26  35 126		indigo 900
140 158 255		indigo a100
 83 109 254		indigo a200
 61  90 254		indigo a400
 48  79 254		indigo a700
225 245 254		light-blue 50
179 229 252		light-blue 100
129 212 250		light-blue 200
 79 195 247		light-blue 300
 41 182 246		light-blue 400
  3 169 244		light-blue 500
  3 155 229		light-blue 600
  2 136 209		light-blue 700
  2 119 189		light-blue 800
  1  87 155		light-blue 900
128 216 255		light-blue a100
 64 196 255		light-blue a200
  0 176 255		light-blue a400
  0 145 234		light-blue a700
241 248 233		light-green 50
220 237 200		light-green 100
197 225 165		light-green 200
174 213 129		light-green 300
156 204 101		light-green 400
139 195  74		light-green 500
124 179  66		light-green 600
104 159  56		light-green 700
 85 139  47		light-green 800
 51 105  30		light-green 900
204 255 144		light-green a100
178 255  89		light-green a200
118 255   3		light-green a400
100 221  23		light-green a700
249 251 231		lime 50
240 244 195		lime 100
230 238 156		lime 200
220 231 117		lime 300
212 225  87		lime 400
205 220  57		lime 500
192 202  51		lime 600
175 180  43		lime 700
158 157  36		lime 800
130 119  23		lime 900
244 255 129		lime a100
238 255  65		lime a200
198 255   0		lime a400
174 234   0		lime a700
255 243 224		orange 50
255 224 178		orange 100
255 204 128		orange 200
255 183  77		orange 300
255 167  38		orange 400
255 152   0		orange 500
251 140   0		orange 600
245 124   0		orange 700
239 108   0		orange 800
230  81   0		orange 900
255 209 128		orange a100
255 171  64		orange a200
255 145   0		orange a400
255 109   0		orange a700
252 228 236		pink 50
248 187 208		pink 100
244 143 177		pink 200
240  98 146		pink 300
236  64 122		pink 400
233  30  99		pink 500
216  27  96		pink 600
194  24  91		pink 700
173  20  87		pink 800
136  14  79		pink 900
255 128 171		pink a100
255  64 129		pink a200
245   0  87		pink a400
197  17  98		pink a700
243 229 245		purple 50
225 190 231		purple 100
206 147 216		purple 200
186 104 200		purple 300
171  71 188		purple 400
156  39 176		purple 500
142  36 170		purple 600
123  31 162		purple 700
106  27 154		purple 800
 74  20 140		purple 900
234 128 252		purple a100
224  64 251		purple a200
213   0 249		purple a400
170   0 255		purple a700
255 235 238		red 50
255 205 210		red 100
239 154 154		red 200
229 115 115		red 300
239  83  80		red 400
244  67  54		red 500
229  57  53		red 600
211  47  47		red 700
198  40  40		red 800
183  28  28		red 900
255 138 128		red a100
255  82  82		red a200
255  23  68		red a400
213   0   0		red a700
224 242 241		teal 50
178 223 219		teal 100
128 203 196		teal 200
 77 182 172		teal 300
 38 166 154		teal 400
  0 150 136		teal 500
  0 137 123		teal 600
  0 121 107		teal 700
  0 105  92		teal 800
  0  77  64		teal 900
167 255 235		teal a100
100 255 218		teal a200
 29 233 182		teal a400
  0 191 165		teal a700
255 253 231		yellow 50
255 249 196		yellow 100
255 245 157		yellow 200
255 241 118		yellow 300
255 238  88		yellow 400
255 235  59		yellow 500
253 216  53		yellow 600
251 192  45		yellow 700
249 168  37		yellow 800
245 127  23		yellow 900
255 255 141		yellow a100
255 255   0		yellow a200
255 234   0		yellow a400
255 214   0		yellow a700
236 239 241		blue-grey 50
207 216 220		blue-grey 100
176 190 197		blue-grey 200
144 164 174		blue-grey 300
120 144 156		blue-grey 400
 96 125 139		blue-grey 500
 84 110 122		blue-grey 600
 69  90 100		blue-grey 700
 55  71  79		blue-grey 800
 38  50  56		blue-grey 900
239 235 233		brown 50
215 204 200		brown 100
188 170 164		brown 200
161 136 127		brown 300
141 110  99		brown 400
121  85  72		brown 500
109  76  65		brown 600
 93  64  55		brown 700
 78  52  46		brown 800
 62  39  35		brown 900
250 250 250		grey 50
245 245 245		grey 100
238 238 238		grey 200
224 224 224		grey 300
189 189 189		grey 400
158 158 158		grey 500
117 117 117		grey 600
 97  97  97		grey 700
 66  66  66		grey 800
 33  33  33		grey 900
  0   0   0	   	black
255 255 255	white

Gimp ggr 文件

[edit | edit source]

“与 GIMP 一起提供的渐变存储在系统渐变文件夹中。默认情况下,您创建的渐变存储在个人 GIMP 目录中的一个名为 gradients 的文件夹中。在这些文件夹中找到的任何渐变文件(以 .ggr 扩展名结尾)将在您启动 GIMP 时自动加载”(来自 gimp 文档) 默认渐变位于 /usr/share/gimp/2.0/gradients 目录中(在窗口中检查:编辑/首选项/目录)

Git 仓库


Gimp 渐变可以通过以下方式创建

  • GUI [63]
  • 在文本编辑器中手动(使用预定义的渐变作为基础)
  • 在自己的程序中

Gimp 渐变文件格式在以下文档中描述

  • GIMP 应用程序参考手册 [64]
  • 源文件
    • app/gradient.c 和 app/gradient_header.h 用于 GIMP 1.3 版本。[65]
    • gimp-2.6.0/app/core/gimpgradient.c

Gimp 渐变段格式

typedef struct {
  gdouble                  left, middle, right;

  GimpGradientColor        left_color_type;
  GimpRGB                  left_color;
  GimpGradientColor        right_color_type;
  GimpRGB                  right_color;

  GimpGradientSegmentType  type;          /*  Segment's blending function  */
  GimpGradientSegmentColor color;         /*  Segment's coloring type      */

  GimpGradientSegment     *prev;
  GimpGradientSegment     *next;
} GimpGradientSegment;

以 GimpConfig 样式格式:[66]

<proposal>
# GIMP Gradient file

(GimpGradient "Abstract 1"
        (segment 0.000000 0.286311 0.572621
                (left-color (gimp-rgba 0.269543 0.259267 1.000000 1.000000))
                (right-color (gimp-rgba 0.215635 0.407414 0.984953 1.000000))
                (blending-function linear)
                (coloring-type rgb))
        (segment ...)
        ...
        (segment ...))
</proposal>

[67]

GIMP Gradient
Name: GMT_hot
3
0.000000 0.187500 0.375000 0.000000 0.000000 0.000000 1.000000 1.000000 0.000000 0.000000 1.000000 0 0
0.375000 0.562500 0.750000 1.000000 0.000000 0.000000 1.000000 1.000000 1.000000 0.000000 1.000000 0 0
0.750000 0.875000 1.000000 1.000000 1.000000 0.000000 1.000000 1.000000 1.000000 1.000000 1.000000 0 0

第一行表明它是一个 gimp 渐变文件。

第二行是渐变的名称。

第三行告诉渐变中的段数。

以下每一行定义每个段的属性,顺序如下:“[68]

  • 左停止点的位置
  • 中间点的位置
  • 右停止点的位置
  • 左停止点的 R
  • 左停止点的 G
  • 左停止点的 B
  • 左停止点的 A
  • 右停止点的 R
  • 右停止点的 G
  • 右停止点的 B
  • 右停止点的 A
  • 混合函数常数
  • 着色类型常数

每行末尾只有两个常数

  • 段的混合函数常数(显然 0=线性,1=曲线,2=正弦,3=球形(递增),4=球形(递减))
  • 段的着色类型常数(可能是 0=RGB,1=HSV(逆时针色相),2=HSV(顺时针色相)[69]
[edit | edit source]

渐变/颜色映射集合

[edit | edit source]

程序

[edit | edit source]

颜色转换

[edit | edit source]


split your hexadecimal color code into 3 values, that could be treated as RGB vectors (RGB decimals) ( from hextoral)

颜色渐变转换

[编辑 | 编辑源代码]

测试你的 

  • 显示器(色域)
  • 显卡
  • 打印机
  • 自己

测试你的色彩能力

[编辑 | 编辑源代码]


如何选择颜色渐变 ?

[编辑 | 编辑源代码]

如何可视化/测试/评估/比较色彩映射?

[编辑 | 编辑源代码]

python 中可视化 matplotlib 内置色彩映射

 python -m viscm view jet

可视化其中一个 viscm 色彩映射

python -m viscm view path/to/colormap_script.py


gnuplot 中使用 test 命令

set palette rgbformulae 21,22,23 
set terminal gif
set output 'p.gif'
test palette

结果:每个颜色通道的二维轮廓

也可以在 RGB 颜色空间中绘制曲线

R 代码

# Install the released version from CRAN:
install.packages("pals")
# Loading required package: pals
require(pals) 
# The palette is converted to RGB or LUV coordinates and plotted in a three-dimensional scatterplot. The LUV space is probably better, but it is easier to tweak colors by hand in RGB space.
pal.cube(cubehelix)
pal.cube(coolwarm)



提示

  • 一个好的离散调色板具有不同的颜色
  • 一个好的连续色彩映射没有显示颜色之间的边界


另请参阅

如何创建感知均匀的渐变?

[编辑 | 编辑源代码]


如何创建具有最大可区分色彩的色彩映射?

[编辑 | 编辑源代码]

如何在色彩映射中使用特殊值?

[编辑 | 编辑源代码]

如何计算图像的平均颜色 ?

[编辑 | 编辑源代码]

假设你在线性 RGB 中执行平均,那么对 RGB 进行平均应该是正确的。如果你的图像采用 sRGB,可以通过对 R、G 和 B 组件执行类似以下操作来去除伽马校正

   float sRGBToLinear(UInt8 component)
   {
       float tempComponent = (float)component / 255.0;
       if (tempComponent <= 0.04045)
       {
           tempComponent = tempComponent / 12.92;
       }
       else
       {
           tempComponent = pow((tempComponent + 0.055) / (1.055), 2.4);
       }
       return tempComponent;
   }

然后,你可以对经过上述转换后的图像中的所有红色值、所有绿色值和所有蓝色值进行平均。然后,你可以执行相反的转换以返回 sRGB

   UInt8 linearRGBTosRGB(float component)
   {
       float tempComponent =  0.0;
       if (component <= 0.00318308)
       {
           tempComponent = 12.92 * component;
       }
       else
       {
           tempComponent = 1.055 * pow(component, 1.0 / 2.4) - 0.055;
       }
       return (UInt8)(tempComponent * 255.0);
   }


请注意,alpha 会使事情变得稍微复杂。如果你使用的是预乘 alpha,则可以简单地应用上述计算来获得平均值。如果你使用的是直接 alpha,则需要在进行平均之前将 R、G 和 B 组件分别乘以 alpha。[74]

如何渲染光谱?

[编辑 | 编辑源代码]

如何从图像中读取(选取)颜色 ?

[编辑 | 编辑源代码]

如何从图像中读取颜色渐变 ?

[编辑 | 编辑源代码]
  • 在线
    • color.adobe 工具
    • color-loom/ Colorloom 是 Sculpting Vis Collaborative 开发的工具,灵感来自于艺术中的调色板创建。该工具从图像中提取一系列色调,并允许用户通过将这些提取的色调拖动到所需的顺序中来创建连续的色彩映射,所有这些都可以在同一个界面中完成。这些色彩映射可以以多种格式导出,以便在主要的可视化软件中使用。

如何从图像中提取调色板 ?

[编辑 | 编辑源代码]
  • Colores.py—从你最喜欢的图像中提取调色板[75]
  • 颜色方案提取[76]
  • 使用 Image Magic [77]
  • 使用 Gimp [78]
  • "在 fractalshades 中有一个小工具,它可以从你在图像上绘制的线条中交互式地获取颜色映射,编辑器看起来像附带的图片。并不完美,但我发现它很有用(在“工具”部分)。然后可以在程序中使用cmap或将其导出以供日后使用(目前,只导出到该程序特有的txt格式)。" Geoffroy Billotey (GBillotey)[79]

如何从图像文件提取ICC配置文件?

[edit | edit source]

使用 Image Magic:[80]

convert photo.jpg profile.icc


如何查看ICC配置文件?

exiftool a.icc


示例输出

ExifTool Version Number         : 12.40
File Name                       : vw1.icc
Directory                       : .
File Size                       : 548 bytes
File Modification Date/Time     : 2023:11:12 20:48:16+01:00
File Access Date/Time           : 2023:11:12 20:48:47+01:00
File Inode Change Date/Time     : 2023:11:12 20:48:16+01:00
File Permissions                : -rw-rw-r--
File Type                       : ICC
File Type Extension             : icc
MIME Type                       : application/vnd.iccprofile
Profile CMM Type                : Apple Computer Inc.
Profile Version                 : 4.0.0
Profile Class                   : Display Device Profile
Color Space Data                : RGB
Profile Connection Space        : XYZ
Profile Date Time               : 2018:06:24 13:22:32
Profile File Signature          : acsp
Primary Platform                : Apple Computer Inc.
CMM Flags                       : Not Embedded, Independent
Device Manufacturer             : Unknown (OPPO)
Device Model                    : 
Device Attributes               : Reflective, Glossy, Positive, Color
Rendering Intent                : Perceptual
Connection Space Illuminant     : 0.9642 1 0.82491
Profile Creator                 : Apple Computer Inc.
Profile ID                      : 0
Profile Description             : Display P3
Profile Copyright               : Copyright Apple Inc., 2017
Media White Point               : 0.95045 1 1.08905
Red Matrix Column               : 0.51512 0.2412 -0.00105
Green Matrix Column             : 0.29198 0.69225 0.04189
Blue Matrix Column              : 0.1571 0.06657 0.78407
Red Tone Reproduction Curve     : (Binary data 32 bytes, use -b option to extract)
Chromatic Adaptation            : 1.04788 0.02292 -0.0502 0.02959 0.99048 -0.01706 -0.00923 0.01508 0.75168
Blue Tone Reproduction Curve    : (Binary data 32 bytes, use -b option to extract)
Green Tone Reproduction Curve   : (Binary data 32 bytes, use -b option to extract)

如何根据任何初始颜色找到更亮和更暗的颜色?

[edit | edit source]
  // darker by C. Wayne Brown
  newR = R + (0-R)*t;  // where t varies between 0 and 1
  newG = G + (0-G)*t;  // where t varies between 0 and 1
  newB = B + (0-B)*t;  // where t varies between 0 and 1
  
  
  // lighter C. Wayne Brown
  newR = R + (1-R)*t;  // where t varies between 0 and 1
  newG = G + (1-G)*t;  // where t varies between 0 and 1
  newB = B + (1-B)*t;  // where t varies between 0 and 1

如何去除渐变色带?

[edit | edit source]


如何生成和优化最佳不同颜色的调色板

[edit | edit source]

如何模拟天空的颜色?

[edit | edit source]

如何制作高质量图像?

[edit | edit source]

渐变轮廓

[edit | edit source]
  • 由 Alan Gibson 描述。[81]

美丽的渐变示例

[edit | edit source]

另请参阅

[edit | edit source]

参考文献

[edit | edit source]
  1. dsp.stackexchange question: why-do-we-use-the-hsv-colour-space-so-often-in-vision-and-image-processing
  2. stackoverflow question:how-can-i-plot-nan-values-as-a-special-color-with-imshow
  3. matplotlib: Colormap set_bad
  4. Completely Painless Programmer's Guide to XYZ, RGB, ICC, xyY, and TRCs by Elle Stone
  5. fractalforums.org: smooth-1d-coloring
  6. observablehq mjbo: perceptually-uniform-color-models
  7. R2.1/2.C(1/2) by Robert Munafo
  8. Color by Robert Munafo
  9. Mandelbrot and Julia sets with PANORAMIC and FreeBASIC By jdebord
  10. The Mandelbrot Function by John J. G. Savard
  11. The Mandelbrot Function 2 by John J. G. Savard
  12. fractalforums.org/: 2d-coloring
  13. Visualizing complex analytic functions using domain coloring by Hans Lundmark
  14. w3docs color-hwb
  15. New gradient interpolation options ( Last updated on May 24, 2023) from Adobe
  16. Optimizing Oklab gradients by Aras Pranckevičius.
  17. drafts csswg org: css-color-4
  18. drafts csswg.org: css-color-4
  19. Tom Beddard 的分形浏览器 Pixel Bender 滤镜
  20. Delphi TColor 格式是什么?在 ACASystems 上
  21. Delhi TColor 在 efg2.com 上
  22. 维基百科:颜色查找表
  23. fractalforums : 使用贝塞尔插值创建好的调色板
  24. FracTest : 调色板
  25. stefanbion : 分形生成器和颜色映射/
  26. nvidia gpu gems2 : 使用查找表加速颜色
  27. Paul Tol 的笔记
  28. gmic : 颜色预设
  29. 分形论坛 > 分形软件 > 分形程序 > Windows 分形软件 > Fractal eXtreme > 在 FractInt 和 Fractal eXtreme 调色板之间转换
  30. stackoverflow 问题 : 曼德尔布罗集渲染的平滑光谱
  31. 查理·劳埃德的彩虹
  32. Stefan Bion : 颜色映射
  33. stackoverflow 问题 : 维基百科中使用哪种颜色渐变来给曼德尔布罗集上色
  34. 在 JavaScript 中制作烦人的彩虹 Jim Bumgardner 的教程
  35. 克里斯托弗·威廉姆斯的 mandel.js
  36. 克里斯托弗·威廉姆斯的自定义调色板
  37. David Wees 发布的 Gradient jQuery 插件
  38. Richel Bilderbeek 的 C++ 函数
  39. 曼德尔布罗集的多波浪着色
  40. 直方图着色实际上是拉伸(不是真正的直方图)
  41. 罗伯特·穆纳福的色彩
  42. 使用 PANORAMIC 和 FreeBASIC 的曼德尔布罗集和朱利亚集 让-德博德
  43. 柯蒂斯·T·麦克穆伦的 c 程序
  44. 帕维尔的颜色渐变生成器
  45. 颜色渐变文件格式说明
  46. 29 种颜色图格式... 彼得·科维西
  47. GIMP 附加组件:类型、安装、管理 亚历山大·普罗库丁
  48. Fractint 调色板映射和映射文件
  49. matplotlib: 颜色图操作
  50. matplotlib 颜色图
  51. 维基百科:查找表
  52. gnofract4d 手册
  53. 肯尼斯·莫兰德:颜色图
  54. w3.org 文档 : 渐变
  55. stackoverflow 问题 : 如何计算 CSS 渐变路径 ?
  56. CSS 颜色中的新函数、渐变和色调(级别 4)史密斯 2023 年 5 月 3 日
  57. 开发人员 chrome 文章:css-color-mix
  58. w:颜色查找表
  59. 关于 GIMP 和 Inkscape 的 RGB 调色板集合(还有 Aseprite、Drawpile、Krita 和 MyPaint)Dezmerean Robert
  60. stackoverflow 问题:gimp-palette-file-gpl-format-语法
  61. 将自定义调色板添加到 GIMP 和 Inkscape Dezmerean Robert
  62. gimp 加载调色板函数的源代码
  63. gimp-gradient-editor-dialog 文档
  64. GimpGradient 文档在 GIMP 应用程序参考手册中
  65. [Gimp-developer] GIMP 渐变文件的格式
  66. [Gimp-developer] GIMP 渐变文件的格式
  67. [Gimp-developer] GIMP 渐变文件的格式
  68. Vinay S Raikar 的 gpr 格式说明
  69. 在 JavaFx 中模拟 ggr/GIMP 渐变
  70. CCC-Tool
  71. imagemagick : 渐变
  72. 戴夫·格林的 'cubehelix' 色彩方案
  73. 科学可视化的分歧颜色图 - 肯尼斯·莫兰德
  74. 计算机图形学 SE 问题:计算图像的平均颜色
  75. 从您最喜欢的图像中提取调色板,作者:John Mangual
  76. algorithmia : 从您最喜欢的网站创建自定义配色方案
  77. ImageMagick v6 示例 -- 颜色量化和抖动
  78. 从图像中提取调色板/颜色表的工具
  79. fractalforums.org : 优美有效的分形着色
  80. rawpedia: 如何提取和检查 ICC 配置文件?
  81. 梯度轮廓,作者:Alan Gibson
华夏公益教科书