colours.ps


NAME

      colours.ps - Some useful colour-handling stuff in PostScript


SYNOPSIS

 (/home/wherever/ps/lib/colours.ps) run
 % to send it to a printer see include_run . . .

 palegreen setrgbcolor

 blue 0.6 grey 0.4 rgbmix setrgbcolor

 /darkskin paleorange 0.4 brown 0.6 rgbmix rgbdef
 darkskin setrgbcolor

 /contourcolour [ 0 blue 50 yellow 100 green 150 grey 200 white ]
    altitude rgbinterpolate rgbdef

 paleorange rgb2gray setgray  % same brightness as the paleorange

 /equivalentgray palegreen rgb2gray def

 orange 0.9 adjustbrightness setrgbcolor
 violet palegreen rgb2gray adjustbrightness setrgbcolor

 50 100 500 170 darkblue white    true -0.8 rectgradientfill
 50 270 500 500 white    paleblue true  0.3 rectgradientfill
 250 270 50 100 yellow  red 0.3 radialgradientfill

[ red black darkgrey ] randomrgb setrgbcolor


DESCRIPTION

This module implements in PostScript some RGB colours and colour-handling procedures to help an artist using PostScript.


COLOURS

colours.ps defines the following colours:

You can use rgbmix and adjustbrightness to mix yourself any other colours that you may need, just like a painter would.


PROCEDURES

rgbmix rgbinterpolate rectgradientfill radialgradientfill rgbdef rgbget randomrgb rgb2gray adjustbrightness pathbboxwh

colour1 weight1   colour2 weight2   rgbmix

The above invocation leaves on the stack, in r g b three-number form, a colour intermediate between colour1 and colour2. The arguments are:
colour1 is the first colour, in r g b three-number form
weight1 is the numerical weight that will be given to the first colour in the mixing
colour2 is the second colour, in r g b three-number form
weight2 is the numerical weight that will be given to the second colour in the mixing

The weights should add up to one, but don't have to; they get normalised to total 1.0 automatically.
rgbmix uses non-linear mixing, to conform to the way the eye sees these things.

[ a1 colour1 .. aN colourN ]   a   rgbinterpolate

The above invocation leaves on the stack, in r g b three-number form, a colour which depends on where the number a lies in relation to the series of numbers a1,a2..aN.

It is expected that a1,a2..aN are in ascending order !
If a is a1 or less, colour1 will be returned,
if a is between a1 and a2, rgbmix is used to interpolate between them,
If a is a2 colour2 will be returned,
if a is between a2 and a3 rgbmix is used to interpolate between them,
if a is aN or more, colourN will be returned.
For example:
[ .5 paleblue .51 white 1 mediumgray ] z rgbinterpolate setrgbcolor
would transform a brownian landscape in z into a sky with clouds ...

x y width height startrgb endrgb vertical convexity   rectgradientfill

The above invocation, conceived as a sort of extension of rectfill, fills the rectangle with a colour-gradient, starting at colour startrgb and ending with endrgb.
If vertical is true, the starting colour is at the bottom (y) and the ending colour at the top (y+height).
If vertical is false, the starting colour is on the left (x) and the ending colour on the right (x+width).
The convexity parameter should lie betwen -1.0 and 1.0. If it is zero, the colour is interpolated linearly; otherwise it is interpolated quadratically, such that if convexity is positive the colour changes fastest at the start (the bottom or left), and if convexity is negative the colour changes fastest towards the end (the top or right).

x y r1 r2 startrgb endrgb convexity   radialgradientfill

The above invocation, conceived in the spirit of rectgradientfill, fills a circular ring with a colour-gradient, starting at colour startrgb at radius r1 and ending with endrgb at radius r2.
The convexity parameter should lie betwen -1.0 and 1.0. If it is zero, the colour is interpolated linearly; otherwise it is interpolated quadratically, such that if convexity is positive the colour changes fastest at the start (r1), and if convexity is negative the colour changes fastest towards the end (r2).

/name_of_colour r g b   rgbdef

The above invocation causes name_of_colour to be defined as { r g b } so it's like a three-dimensional version of def.
Note that because a colour has three components, the common /x exch def idiom doesn't work with rgbdef; you'll need something like this instead:
    /mynewcolour 4 1 roll rgbdef

[ red black grey ]   1   rgbget

This extracts the colour black and puts it on the stack (in r g b form), so it's like a three-dimensional version of get.

[ red black darkgrey ]   randomrgb

The above invocation chooses at random one of the colours in the array (red, black and darkgrey in this example), and then leaves that colour on the stack.

By default it will make different a choice every time you load the page, so if you need consistency you should invoke srand first.

r g b   rgb2gray

The above invocation causes the r g b colour to be converted to its equivalent gray value, which is then left on the stack. The conversion follows the NTSC video standard, which determines how a colour television signal is rendered on a black and white television: gray = .3 * red + .59 * green + .11 * blue

Printers and Graphic displays differ widely, and the NTSC standard does not necessarily produce a gray value which you will perceive, on your Graphic display, as having the same luminance as the original colour. If this becomes an issue for you on some particular display, then the callibrate_rgb2gray variable will allow you to callibrate the conversion.

r g b   gray   adjustbrightness

The above invocation causes the r g b colour to be adjusted in brightness until it matches the gray value, as judged by the rgb2gray subroutine. The resulting colour is left on the stack in r g b form.

Where possible, all three components of the colour are scaled by the same factor; this adjusts the Brightness of the colour. But if one of those components would as a result exceed 1.0, then it is fixed at 1.0 and the result is mixed with white until it matches gray; this reduces the Saturation of the colour.

An excellent discussion of the many uses of equiluminant colours of different hues can be found in Margret Livingstone's book Vision and Art, the Biology of Seeing.

pathbboxwh

This is the same as the standard pathbbox procedure, except that it leaves the box on the stack in the form:
  llx lly width height
ready for use by rectclip, rectfill or rectgradientfill.   The standard pathbbox leaves it in the form: llx lly urx ury

For example:
  (a string) charpath clip
  clippath pathbboxwh  red orange false 0.5 rectgradientfill


Callibrating rgb2gray to fit your display

Printers and graphic displays differ widely, and the NTSC standard which is used by rgb2gray and adjustbrightness does not necessarily produce a gray value which you will perceive, on your display, as having the same luminance as the original colour. If this becomes an issue for you, a simple one-parameter adjustment is available to help you customise the formula to fit your display. Usage:

 (/home/wherever/ps/lib/colours.ps) run
 . . .
 /callibrate_rgb2gray 0.4 def   % between 0.0 and 1.0
 orange rgb2gray setgray ...

If you set callibrate_rgb2gray to 0.0, then the standard NTSC conversion will be performed. The NTSC formula converts evenly mixed (greyish) colours correctly. But the NTSC formula thinks that red has the same luminance as 0.3 setgray, whereas your printer or display may well show the gray as being much darker. As you increase the value of callibrate_rgb2gray, the purer colours (reddish, greeninsh, blueish) will be converted lighter, without affecting the conversion of the more neutral (greyish) colours. For example, on my CRT, /callibrate_rgb2gray 0.4 def gave the best results. If you leave callibrate_rgb2gray unset, its default value is now 0.15

A PostScript page callibrate_rgb2gray.ps is supplied to help you measure what callibrate_rgb2gray should be to suit a particular display or printer. Various values of callibrate_rgb2gray are printed down the left side of the page; choose the value which gives each grey rectangle in the row the same luminance as its neighbouring colour rectangles. Choose the best compromise value across all the colour columns.

As mentioned, for my CRT the best setting was 0.4, and for my current monitor it is 0.2. I'd enjoy hearing what the optimum is for other devices; if they cluster around a particular value I'll make that the default.


INSTALL

To install: go to www.pjb.com.au/comp/free/colours.ps.txt and save the file to your local disc.
Rename it to colours.ps and move it into some appropriate directory such as ~/ps/lib . . .
Or, first change directory to where you keep your PostScript libraries:
    cd /home/wherever/ps/lib/
(or wherever)   and then either:
    wget -O colours.ps http://www.pjb.com.au/comp/free/colours.ps.txt
or:
    curl http://www.pjb.com.au/comp/free/colours.ps.txt -o colours.ps

Or, get it from github:
    git clone https://github.com/peterbillam/postscriptlib


AUTHOR

Peter J Billam   www.pjb.com.au/comp/contact.html


CHANGES

 20160629 add paleyellow
 20160623 add radialgradientfill
 20160519 add pathbboxwh
 20160515 add darkorange
 20160425 fix the small gap rectgradientfill left at the beginning
 20160421 add randomrgb, useful eg. for foliage
 20140703 add rectgradientfill, useful eg. for art deco and psychedelia
 20060121 callibrate_rgb2gray now defaults to 0.15
 20060121 adjustbrightness defends against division by zero
 20031024 add callibrate_rgb2gray mechanism
 20031020 add pink as synonym for palered
 20031017 add adjustbrightness
 20031016 add rgb2gray
 20030610 some extra colours
 20030313 roll in some stuff from line_drawing.ps
 20030303 rgbinterpolate now working :-)
 20030225 add nonlinearise and nonlinearrgbmix
 20001214 rgbmix does non-linear mixing
 20001213 corrected some colours after visual test
 20001212 Colour-Handling Utilities for Postscript

SEE ALSO

As examples, see www.pjb.com.au/art/posters/ . . .

See also sample1.ps.txt and sample4.ps.txt . . .   Save the file to your local disc, rename it to sample1.ps or sample4.ps and edit it so that the run statement(s) near the beginning point to the directory where line_drawing.ps and colours.ps are installed on your system. Then use GhostView or equivalent to view it. If you wish to print it out, feel free to use something like include_run to roll the run-files in.
For easy viewing, PDF versions of the results are in sample1.pdf and sample4.pdf . . .

See also


Back to P J B Computing or to www.pjb.com.au . . .