Last modified on 27 September 2014, at 13:21

Color Theory/Color gradient

TheoryEdit

Example of interesting color gradient

IntroductionEdit

Types of color gradientEdit

Color gradients can be named by :

  • dimension
  • color model
  • number of segments of gradient
  • function used to create gradient
  • Number of colors

DimensionEdit

1DEdit

Here color of pixel is proportional to 1D variable. For example in 2D space ( complex plane where point z = x+y*i) :

  • position with respect to x-axis of Cartesian coordinate system : x
  • distance to origin : r=abs(z)
  • complex angle angle=arg(z)

An example of a function to return a color that is linearly between two given colors:

 
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

2DEdit

Domain coloring plot of the function
ƒ(x) =(x2 − 1)(x − 2 − i)2/(x2 + 2 + 2i). The hue represents the function argument, while the saturation represents the magnitude.


Because color can be treated as more than 1D value it is used to represent more than one ( real or 1D) variable. For example :

  • Robert Munafo uses 2 values from HSV model of color [1][2][3]
  • John J. G. Savard uses own function [4][5]

3DEdit

  • Hans Lundmark page[6]

Color modelEdit

RGBEdit

HSVEdit

#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;
}

FunctionEdit

One can use any function in each segment of gradient. Output of function is scaled to range of color component.

Number of colorsEdit

Number of color is determined by color depth : from 2 colors to 16 mln of colors.

Repetition and offsetEdit

Direct repetition :

Color is proportional to position <0;1> of color in color gradient. if position > 1 then we have repetition of colors. it maybe useful

Mirror repetition  :

"colorCycleMirror - This will reflect the colour gradient so that it cycles smoothly " [7]

Offset :

How to use color gradients in computer programsEdit

Palette graphics, palette replacement mechanism

First find what format of color you need in your program.[8][9]

After that there are 3 ways making gradient :

  • gradient functions
  • gradient files
  • palette

PaletteEdit

# 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" );
}

Gradient functionsEdit

Examples :

  • Javascript using jQuery [10]
  • C++ function by Richel Bilderbeek [11]
  • Multiwave coloring for Mandelbrot[12]

HSV gradientEdit

  • explanation by Robert P. Munafo[13]
  • Basic code and images by Jean Debord[14]
  • c programs by Curtis T McMullen [15]

Linear RGB gradient with 6 segmentsEdit

Result and diagram of GiveRainbowColor function

Here gradient consists from 6 segments. In each segment only one RGB component of color is changed using linear function.

Delphi versionEdit

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

C versionEdit

Input of function are 2 variables :

  • position of color in gradient, (a normalized float between 0.0 and 1.0 )
  • color as an array of RGB components ( integer without sign from 0 to 255 )

This function does not use direct outoput ( void) but changes input variables color. One can use it this way:

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 versionEdit

// 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;
}

Gradient filesEdit

File types for color gradientEdit

There are special file types for color gradients[16]:

  • The GIMP uses the files with .ggr extension [17]
  • Fractint uses .map files [18]
  • UltraFractal uses .ugr - These files can contain multiple gradients
  • ual - old Ultra Fractal gradient file

Gnofract4D saves gradients only inside the graphic file, not as separate file. [19]

Fractint map filesEdit

The default filetype extension for color-map files is ".MAP". These are ASCII text files. Consist of a series of RGB triplet values (one triplet per line, encoded as the red, green, and blue [RGB] components of the color). Color map ( or palette) is used as a colour look-up table[20] Default color map is in the Default.map file :

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 ggr filesEdit

"The gradients that are supplied with GIMP are stored in a system gradients folder. By default, gradients that you create are stored in a folder called gradients in your personal GIMP directory. Any gradient files (ending with the extension .ggr) found in one of these folders, will automatically be loaded when you start GIMP" ( from gimp doc ) Default gradients are in /usr/share/gimp/2.0/gradients directory ( check it in a window : Edit/preferences/directories)


Gimp gradients can be created thru :

  • GUI [21]
  • manually in text editor ( use predefined gradients as a base)
  • in own programs

Gimp gradient file format is described in:

  • GIMP Application Reference Manual [22]
  • source files :
    • app/gradient.c and app/gradient_header.h for GIMP 1.3 version. [23]
    • gimp-2.6.0/app/core/gimpgradient.c

Gimp Gradient Segment format :

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;


In GimpConfig style format:[24]

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

[25]


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


First line says it is a gimp gradient file.

Second line is a gradient's name.

Third line tells the number of segments in the gradient.

Each line following defines the property of each segment in following order :"[26]

  • position of left stoppoint
  • position of middle point
  • position of right stoppoint
  • R for left stoppoint
  • G for left stoppoint
  • B for left stoppoint
  • A for left stoppoint
  • R for right stoppoint
  • G for right stoppoint
  • B for right stoppoint
  • A for right stoppoint
  • Blending function constant
  • coloring type constant


There are only two constants at the end of each line:

  • the blending function constant of the segment (apparently 0=Linear, 1=Curved, 2=Sinusoidal, 3=Spherical (increasing), 4=Spherical (decreasing))
  • the coloring type constant of the segment (probably 0=RGB, 1=HSV (counter-clockwise hue), 2=HSV (clockwise hue)[27]

How to use gradient files in computer programsEdit

Collections of gradientsEdit

  • gradcentral
  • Cpt-city
  • gimp gradients (ggr files) are in directory : /usr/share/gimp/2.0/gradients/


How to extract color pallete from image ?Edit

  • Colores.py -- extract color palletes from your favorite images [28]
  • using Image Magic [29]
  • using Gimp [30]

ReferencesEdit

  1. R2.1/2.C(1/2) by Robert Munafo
  2. Color by Robert Munafo
  3. Mandelbrot and Julia sets with PANORAMIC and FreeBASIC By jdebord
  4. The Mandelbrot Function by John J. G. Savard
  5. The Mandelbrot Function 2 by John J. G. Savard
  6. [http://www.mai.liu.se/~halun/complex/domain_coloring-unicode.html Visualizing complex analytic functions using domain coloring by Hans Lundmark ]
  7. The Fractal Explorer Pixel Bender filters by Tom Beddard
  8. What's Delphi TColor format? at ACASystems
  9. Delhi TColor at efg2.com
  10. Gradient jQuery plugin Posted by David Wees
  11. C++ function by Richel Bilderbeek
  12. Multiwave coloring for Mandelbrot
  13. Color by Robert Munafo
  14. Mandelbrot and Julia sets with PANORAMIC and FreeBASIC By Jean Debord
  15. c programs by Curtis T McMullen
  16. Color gradient file formats explained
  17. GIMP add-ons: types, installation, management by Alexandre Prokoudine
  18. Fractint Palette Maps and map files
  19. gnofract4d manual
  20. w:Colour look-up table
  21. gimp-gradient-editor-dialog doc
  22. GimpGradient doc at GIMP Application Reference Manual
  23. [Gimp-developer] Format of GIMP gradient files
  24. [Gimp-developer] Format of GIMP gradient files
  25. [Gimp-developer] Format of GIMP gradient files
  26. gpr format description by Vinay S Raikar
  27. Emulating ggr/GIMP gradient in JavaFx
  28. extract color palletes from your favorite images by John Mangual
  29. ImageMagick v6 Examples -- Color Quantization and Dithering
  30. Tool to extract palette / color table from image