跳转到内容

颜色理论/颜色渐变

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

颜色渐变的类型

[编辑 | 编辑源代码]

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

这里像素的颜色与 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],
  • 撤销预乘:alpha 值为 0.5,这将得到 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]
  • c 程序由 Curtis T McMullen 提供 [43]

线性 RGB 渐变,包含 6 个段

[编辑 | 编辑源代码]


彩虹渐变


这里渐变由 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)
伽马编码的 sRGB 渐变,中间色过深,略微不饱和,并带有轻微的紫色色调
linear-gradient(in Oklab to right, white, #01E)
Oklab 渐变,提供更感知均匀的结果,完全没有紫色色调
linear-gradient(to right, #a8c0ff, #3f2b96);
Ocean View
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%);


black-to-white-gradient-in-each-space[57]


描述 预览图像
Oklab,感知均匀的结果
oklch
lab
lch
srgb
srgb-linear
hsl
hwb
xyz
xyz-d50
xyz-d65
代码 预览
.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%);
}


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 地图文件

[编辑 | 编辑源代码]

颜色映射文件的默认文件类型扩展名为“.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 的文件夹中。启动 GIMP 时,会自动加载在这些文件夹中找到的任何渐变文件(以 .ggr 扩展名结尾)。"(来自 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)

颜色渐变转换

[edit | edit source]

测试

[edit | edit source]

测试您的

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

测试您的颜色识别能力

[edit | edit source]


如何选择颜色渐变?

[edit | edit source]

如何可视化/测试/评估/比较颜色图?

[edit | edit source]

python 中可视化 matplotlib 内置颜色图

 python -m viscm view jet

可视化 viscm 颜色图之一

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


gnuplot 中使用测试命令

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

结果:每个颜色通道的 2D 轮廓

也可以通过 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)



技巧

  • 好的离散调色板具有不同的颜色
  • 好的连续颜色图不会显示颜色之间的边界


另见

如何制作感知一致的渐变?

[edit | edit source]


如何制作具有最大可区分颜色的颜色图?

[edit | edit source]

如何在颜色图中使用特殊值?

[edit | edit source]

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

[edit | edit source]

假设您在线性 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]

如何渲染光谱?

[edit | edit source]

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

[edit | edit source]

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

[edit | edit source]
  • 在线
    • color.adobe 工具
    • color-loom/ Colorloom 是由 Sculpting Vis Collaborative 开发的工具,其灵感来自模仿艺术中的调色板创建。该工具从图像中提取一系列色调,并使用户能够通过将这些提取的色调拖动到所需的顺序来创建连续的颜色图,所有这些都在同一个界面中。这些颜色图可以以多种格式导出,供主要可视化软件使用。

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

[edit | edit source]
  • 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)

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

[编辑 | 编辑源代码]
  // 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

如何消除渐变色带?

[编辑 | 编辑源代码]


如何生成和优化最佳区分颜色的调色板

[编辑 | 编辑源代码]

如何模拟天空的颜色?

[编辑 | 编辑源代码]

如何制作高质量的图像?

[编辑 | 编辑源代码]

渐变轮廓

[编辑 | 编辑源代码]
  • Alan Gibson 的描述。[81]

美丽的渐变示例

[编辑 | 编辑源代码]

参考文献

[编辑 | 编辑源代码]
  1. dsp.stackexchange 问题:why-do-we-use-the-hsv-colour-space-so-often-in-vision-and-image-processing
  2. stackoverflow 问题:how-can-i-plot-nan-values-as-a-special-color-with-imshow
  3. matplotlib: Colormap set_bad
  4. 完全无痛的程序员 XYZ、RGB、ICC、xyY 和 TRC 指南,作者:Elle Stone
  5. fractalforums.org: smooth-1d-coloring
  6. observablehq mjbo: perceptually-uniform-color-models
  7. Robert Munafo 的 R2.1/2.C(1/2)
  8. Robert Munafo 的颜色
  9. 使用 PANORAMIC 和 FreeBASIC 的 Mandelbrot 和 Julia 集,作者:jdebord
  10. Mandelbrot 函数,作者:John J. G. Savard
  11. Mandelbrot 函数 2,作者:John J. G. Savard
  12. fractalforums.org/: 2d-coloring
  13. 使用域着色可视化复分析函数,作者:Hans Lundmark
  14. w3docs color-hwb
  15. Adobe 的新渐变插值选项(上次更新于 2023 年 5 月 24 日)
  16. 优化 Oklab 渐变,作者:Aras Pranckevičius。
  17. drafts csswg org: css-color-4
  18. drafts csswg.org: css-color-4
  19. Tom Beddard 的分形浏览器 Pixel Bender 过滤器
  20. ACASystems 上的 Delphi TColor 格式是什么?
  21. efg2.com 上的 Delhi TColor
  22. 维基百科:颜色查找表
  23. fractalforums : 使用贝塞尔曲线插值创建好的调色板
  24. FracTest : 调色板
  25. stefanbion : fraktal-generator 和 colormapping/
  26. nvidia gpu gems2 : 使用查找表加速颜色
  27. Paul Tol 的笔记
  28. gmic : color_presets
  29. 分形论坛 > 分形软件 > 分形程序 > Windows 分形软件 > Fractal eXtreme > FractInt 和 Fractal eXtreme 调色板之间的转换
  30. stackoverflow 问题:用于曼德布罗特集合渲染的平滑频谱
  31. 关于彩虹 由 Charlie Loyd
  32. Stefan Bion:颜色映射
  33. stackoverflow 问题:维基百科中用于为曼德布罗特着色的颜色梯度
  34. 在 javascript 中制作恼人的彩虹 由 Jim Bumgardner
  35. mandel.js 由 Christopher Williams
  36. 自定义调色板 由 Christopher Williams
  37. 梯度 jQuery 插件 由 David Wees
  38. C++ 函数 由 Richel Bilderbeek
  39. 曼德布罗特的多波着色
  40. 直方图着色实际上是在拉伸(不是真正的直方图)
  41. 颜色 由 Robert Munafo
  42. 使用 PANORAMIC 和 FreeBASIC 的曼德布罗特集和朱莉娅集 由 Jean Debord
  43. c 程序 由 Curtis T McMullen
  44. 颜色梯度生成器 由 Pavel
  45. 颜色梯度文件格式说明
  46. 29 种颜色映射格式... 由 Peter Kovesi
  47. GIMP 附加组件:类型、安装、管理 由 Alexandre Prokoudine
  48. FractInt 调色板映射和映射文件
  49. matplotlib:颜色映射操作
  50. matplotlib 颜色映射
  51. 维基百科:查找表
  52. gnofract4d 手册
  53. kenneth moreland:颜色映射
  54. w3.org 文档:梯度
  55. stackoverflow 问题:如何计算 CSS 梯度路径?
  56. CSS 颜色中的新函数、梯度和色调(级别 4) 由 Smith 2023 年 5 月 3 日
  57. 开发人员 Chrome 文章:css-color-mix
  58. 维基百科:颜色查找表
  59. 关于 GIMP 和 Inkscape 的 RGB 调色板集合(也适用于 Aseprite、Drawpile、Krita 和 MyPaint) 由 Dezmerean Robert
  60. stackoverflow 问题:gimp-palette-file-gpl 格式语法
  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. gpr 格式说明 由 Vinay S Raikar
  69. 在 JavaFx 中模拟 ggr/GIMP 梯度
  70. CCC 工具
  71. imagemagick:梯度
  72. Dave Green 的“cubehelix”配色方案
  73. 科学可视化的发散颜色映射 - Kenneth Moreland
  74. computergraphics SE 问题:计算图像的平均颜色
  75. 从您喜欢的图像中提取颜色调色板 由 John Mangual
  76. algorithmia:从您喜欢的网站创建自定义配色方案/
  77. ImageMagick v6 示例 - 颜色量化和抖动
  78. 用于从图像中提取调色板/颜色表的工具
  79. fractalforums.org:分形的美丽而有效的着色
  80. rawpedia:如何提取和检查 ICC 配置文件?
  81. 梯度轮廓 由 Alan Gibson
华夏公益教科书