Color Space
This chapter describes the ImageN color space, transparency, and the color conversion operators. ImageN follows the Java AWT color model.
- 5.1 Introduction
- 5.2 Color Management
- 5.3 Transparency
- 5.4 Color Conversion
- 5.5 Non-standard Linear Color Conversion (BandCombine)
5.1 Introduction
Digital images, specifically digital color images, come in several different forms. The form is often dictated by the means by which the image was acquired or by the image's intended use.
One of the more basic types of color image is RGB, for the three primary colors (red, green, and blue). RGB images are sometimes acquired by a color scanner or video camera. These devices incorporate three sensors that are spectrally sensitive to light in the red, green, and blue portions of the spectrum. The three separate red, green, and blue values can be made to directly drive red, green, and blue light guns in a CRT. This type of color system is called an additive linear RGB color system, as the sum of the three full color values produces white.
Printed color images are based on a subtractive color process in which cyan, magenta, and yellow (CMY) dyes are deposited onto paper. The amount of dye deposited is subtractively proportional to the amount of each red, blue, and green color value. The sum of the three CMY color values produce black.
The black produced by a CMY color system often falls short of being a true black. To produce a more accurate black in printed images, black is often added as a fourth color component. This is known as the CMYK color system and is commonly used in the printing industry.
The amount of light generated by the red, blue, and green phosphors of a CRT is not linear. To achieve good display quality, the red, blue, and green values must be adjusted - a process known as gamma correction. In computer systems, gamma correction often takes place in the frame buffer, where the RGB values are passed through lookup tables that are set with the necessary compensation values.
In television transmission systems, the red, blue, and green gamma-corrected color video signals are not transmitted directly. Instead, a linear transformation between the RGB components is performed to produce a luminance signal and a pair of chrominance signals. The luminance signal conveys color brightness levels. The two chrominance signals convey the color hue and saturation. This color system is called YCC (or, more specifically, YC~b~C~r~).
Another significant color space standard for ImageN is CIEXYZ. This is a widely-used, device-independent color standard developed by the Commission Internationale de l'Éclairage (CIE). The CIEXYZ standard is based on color-matching experiments on human observers.
5.2 Color Management
ImageN uses three primary classes for the management of color:
-
ColorModel
- describes a particular way that pixel values are mapped to colors. AColorModel
is typically associated with anImage
orBufferedImage
and provides the information necessary to correctly interpret pixel values.ColorModel
is defined in thejava.awt.image
package. -
ColorSpace
- represents a system for measuring colors, typically using three separate values or components. TheColorSpace
class contains methods for converting between the original color space and one of two standard color spaces, CIEXYZ and RGB.ColorSpace
is defined in thejava.awt.color
package. -
Color
- a fixed color, defined in terms of its components in a particularColorSpace
.Color
is defined in thejava.awt
package.
5.2.1 Color Models
A ColorModel
is used to interpret pixel data in an image. This includes:
-
Mapping components in the bands of an image to components of a particular color space
-
Extracting pixel components from packed pixel data
-
Retrieving multiple components from a single band using masks
-
Converting pixel data through a lookup table
To determine the color value of a particular pixel in an image, you need to know how the color information is encoded in each pixel. The ColorModel
associated with an image encapsulates the data and methods necessary for translating a pixel value to and from its constituent color components.
ImageN supports five color models:
-
DirectColorModel
- works with pixel values that represent RGB color and alpha information as separate samples and that pack all samples for a single pixel into a single int, short, or byte quantity. This class can be used only with ColorSpaces of typeColorSpace.TYPE_RGB
. -
IndexColorModel
- works with pixel values consisting of a single sample that is an index into a fixed colormap in the default sRGB ColorSpace. The colormap specifies red, green, blue, and optional alpha components corresponding to each index. -
ComponentColorModel
- can handle an arbitraryColorSpace
and an array of color components to match theColorSpace
. This model can be used to represent most color models on most types ofGraphicsDevices
. -
PackedColorModel
- a base class for models that represent pixel values in which the color components are embedded directly in the bits of an integer pixel. APackedColorModel
stores the packing information that describes how color and alpha components are extracted from the channel. TheDirectColorModel
is aPackedColorModel
. -
FloatDoubleColorModel
- works with pixel values that represent color and alpha information as separate samples, using float or double elements.
The following sample code shows the construction of a ComponentColorModel
for an RGB color model.
// Create an RGB color model
int[] bits = { 8, 8, 8 };
ColorModel colorModel = new
ComponentColorModel(ColorSpace.getInstance(ColorSpace.CS_sRGB),
bits, false, false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE);
The following sample code shows the construction of a ComponentColorModel
for a grayscale color model.
// Create a grayscale color model.
ColorSpace cs = ColorSpace.getInstance(ColorSpace.CS_GRAY);
int bits[] = new int[] {8};
ColorModel cm = new ComponentColorModel(cs, bits, false, false,
Transparency.OPAQUE,
DataBuffer.TYPE_BYTE);
The following sample code shows the construction of a FloatDoubleColorModel
for a linear RGB color model.
ColorSpace colorSpace =
ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB);
int[] bits = new int[3];
bits[0] = bits[1] = bits[2] = 32;
ColorModel cm = new FloatDoubleColorModel(colorSpace,
false,
false,
Transparency.OPAQUE,
DataBuffer.TYPE_FLOAT);
API: java.awt.image.ComponentColorModel
ComponentColorModel(ColorSpace colorSpace, int[] bits, boolean hasAlpha, boolean isAlphaPremultiplied, int transparency, int transferType)
API: org.eclipse.imagen.FloatDoubleColorModel
FloatDoubleColorModel(ColorSpace colorSpace, boolean hasAlpha, boolean isAlphaPremultiplied, int transparency, int transferType)
5.2.2 Color Space
The ColorSpace
class represents a system for measuring colors, typically using three or more separate numeric values. For example, RGB and CMYK are color spaces. A ColorSpace
object serves as a color space tag that identifies the specific color space of a Color
object or, through a ColorModel
object, of an Image
, BufferedImage
, or GraphicsConfiguration
.
ColorSpace
provides methods that transform Colors
in a specific color space to and from sRGB
and to and from a well-defined CIEXYZ
color space. All ColorSpace
objects must be able to map a color from the represented color space into sRGB
and transform an sRGB
color into the represented color space.
Table 5-1 lists the variables used to refer to color spaces (such as CS_sRGB
and CS_CIEXYZ
) and to color space types (such as TYPE_RGB
and TYPE_CMYK
).
Name | Description |
---|---|
CS_CIEXYZ | A widely-used, device-independent color standard developed by the Commission Internationale de Eclairage (CIE), based on color-matching experiments on human observers. |
CS_GRAY | Grayscale color space. |
CS_LINEAR_RGB | Linear RGB. Images that have not been previously color-corrected. |
CS_PYCC | PhotoCD YCC conversion color space. A luminance/chrominance standard for Kodak PhotoCD images. |
CS_sRGB | A proposed default "standard RGB" color standard for use over the Internet. |
TYPE_2CLR | A generic two-component color space. |
TYPE_3CLR | A generic three-component color space. |
TYPE_4CLR | A generic four-component color space. |
TYPE_5CLR | A generic five-component color space. |
TYPE_6CLR | A generic six-component color space. |
TYPE_7CLR | A generic seven-component color space. |
TYPE_8CLR | A generic eight-component color space. |
TYPE_9CLR | A generic nine-component color space. |
TYPE_ACLR | A generic 10-component color space. |
TYPE_BCLR | A generic 11-component color space. |
TYPE_CCLR | A generic 12-component color space. |
TYPE_CMY | Any of the family of CMY color spaces. |
TYPE_CMYK | Any of the family of CMYK color spaces. |
TYPE_DCLR | Generic 13-component color spaces. |
TYPE_ECLR | Generic 14-component color spaces. |
TYPE_FCLR | Generic 15-component color spaces. |
TYPE_GRAY | Any of the family of GRAY color spaces. |
TYPE_HLS | Any of the family of HLS color spaces. |
TYPE_HSV | Any of the family of HSV color spaces. |
TYPE_Lab | Any of the family of Lab color spaces. |
TYPE_Luv | Any of the family of Luv color spaces. |
TYPE_RGB | Any of the family of RGB color spaces. |
TYPE_XYZ | Any of the family of XYZ color spaces. |
TYPE_YCbCr | Any of the family of YCbCr color spaces. |
TYPE_Yxy | Any of the family of Yxy color spaces. |
Conversion between Java color spaces is simplified by a set of methods that map a color from a represented color space to either sRGB or CIEXYZ and transform a sRGB or CIEXYZ color space to the represented color space. There are four methods:
-
The
toRGB
method transforms aColor
in the represented color space to aColor
in sRGB. -
The
toCIEXYZ
method transforms aColor
in the represented color space to aColor
in CIEXYZ. -
The
fromRGB
method takes aColor
in sRGB and transforms into the represented color space. -
The
fromCIEXYZ
method takes aColor
in CIEXYZ and transforms into the represented color space.
The sRGB (which stands for "standard" RGB) color space is provided as a convenience to programmers, since many applications are primarily concerned with RGB images. Defining a standard RGB color space makes writing such applications easier. The toRGB
and fromRGB
methods are provided so that developers can easily retrieve colors in this standard space. However, the sRGB color space is not intended for use with highly accurate color correction or conversions.
The sRGB color space is somewhat limited in that it cannot represent every color in the full gamut (spectrum of representable colors) of CIEXYZ color. If a color is specified in some space that has a different gammut than sRGB, using sRGB as an intermediate color space results in a loss of information. The CIEXYZ color space is used as an intermediate color space to avoid any loss of color quality. The CIEXYZ color space is known as the conversion space for this reason. The toCIEXYZ
and fromCIEXYZ
methods support conversions between any two color spaces at a reasonably high degree of accuracy, one color at a time.
API: java.awt.color.ColorSpace
-
abstract float[] toRGB(float[] colorvalue)
-
abstract float[] fromRGB(float[] rgbvalue)
-
abstract float[] toCIEXYZ(float[] colorvalue)
-
abstract float[] fromCIEXYZ(float[] colorvalue)
-
static ColorSpace getInstance(int colorspace)
-
int getType()
5.2.3 ICC Profile and ICC Color Space
The ColorSpace
class is an abstract class. It is expected that particular implementations of subclasses of ColorSpace
will support high performance conversion based on underlying platform color management systems. The ICC_ColorSpace
class is one such implementation provided in the base AWT. Developers can define their own subclasses to represent arbitrary color spaces, as long as the appropriate "to" and "from" conversion methods are implemented. However, most developers can simply use the default sRGB
color space or color spaces that are represented by commonly-available ICC profiles, such as profiles for monitors and printers or profiles embedded in image data.``
The ICC_ColorSpace
class is based on ICC profile data as represented by the ICC_Profile
class. The ICC_Profile
class is a representation of color profile data for device-independent and device-dependent color spaces based on the ICC Profile Format Specification, Version 3.4, August 15, 1997, from the International Color Consortium. ICC profiles describe an input space and a connection space, and define how to map between them.
The ICC_Profile
class has two subclasses that correspond to the specific color types:
-
ICC_ProfileRGB
, which representsTYPE_RGB
color spaces -
ICC_ProfileGray
, which representsTYPE_GRAY
color spaces
5.3 Transparency
Just as images can have color, they can also have transparency. Transparency defines the specular transmission of light through transparent materials, such as glass, or the lack of transparency for completely opaque objects. The amount of transparency is specified by an alpha ɑ value. An alpha value of 0.0 specifies complete translucency; an alpha value of 1.0 specifies complete opacity.
Images can carry transparency information, known as the alpha channel, for each pixel in the image. The alpha value is particularly important when colors overlap. The alpha value specifies how much of the previously-rendered color should show through.
The Java Transparency
interface defines the common transparency modes for implementing classes. Table 5-2 lists the variables used to specify transparency.
Name | Description |
---|---|
BITMASK | Represents image data that is guaranteed to be either completely opaque, with an alpha value of 1.0, or completely transparent, with an alpha value of 0.0. |
OPAQUE | Represents image data that is guaranteed to be completely opaque, meaning that all pixels have an alpha value of 1.0. |
TRANSLUCENT | Represents image data that contains or might contain arbitrary alpha values between and including 0.0 and 1.0. |
Transparency is specified as part of the color model (see Section 5.2.1, "Color Models").
5.4 Color Conversion
The ColorConvert
operation performs a pixel-by-pixel color conversion of the data in a rendered or renderable source image. The data are treated as having no alpha channel, i.e., all bands are color bands. The color space of the source image is specified by the ColorSpace
object of the source image ColorModel
which must not be null.
ImageN does not attempt to verify that the ColorModel
of the destination image is consistent with the ColorSpace
parameter. To ensure that this is the case, a compatible ColorModel
must be provided via an ImageLayout
in the RenderingHints
(see Section 3.7.3, "Rendering Hints").
Integral data are assumed to occupy the full range of the respective data type; floating point data are assumed to be normalized to the range [0.0,1.0]. By default, the destination image bounds, data type, and number of bands are the same as those of the source image.
The ColorConvert
operation takes one parameter:
Parameters | Type | Description |
---|---|---|
colorSpace | ColorSpace | The destination color space. |
For information on color space, see Section 5.2.2, "Color Space."
Listing 5-1 shows a code sample for a ColorConvert
operation.
Listing 5-1 Example ColorConvert Operation
// Read the image from the specified file name.
RenderedOp src = JAI.create("fileload", fileName);
// Create the ParameterBlock.
ParameterBlock pb = new ParameterBlock();
pb.addSource(src).add(colorSpace);
// Perform the color conversion.
RenderedOp dst = JAI.create("ColorConvert", pb);
5.5 Non-standard Linear Color Conversion (BandCombine)
In ImageN, the BandCombine
operation performs a linear color conversion between color spaces other than those listed in Table 5-1. The BandCombine
operation computes a set of arbitrary linear combinations of the bands of a rendered or renderable source image, using a specified matrix. The matrix must have dimension (# of source bands plus one) by (# of desired destination bands).
The BandCombine
operation takes one parameter:
Parameters | Type | Description |
---|---|---|
matrix | double | The matrix specifying the band combination. |
As an example, assume the three-band source image and the matrix shown in Figure 5-1.
The equation to calculate the value of the destination pixel in this example would be:
dst = (255 * 0.25) + (157 * 0.5) + (28 * 0.75)
—————————————–
Figure 5-1 Band Combine Example
In this example, the number of columns in the matrix is equal to the number of bands in the source image. The number of rows in the matrix must equal the number of bands in the destination image. For a destination image with three bands, the values in the second row of the matrix would be used to calculate the values in the second band of the destination image and the values in the third row would be used to calculate the values in the third band.
If the result of the computation underflows or overflows the minimum or maximum value supported by the destination image, it will be clamped to the minimum or maximum value, respectively.
Listing 5-2 shows a code sample for a BandCombine
operation.
Listing 5-2 Example BandCombine Operation
// Create the matrix.
// Invert center band.
double[][] matrix = {
{ 1.0D, 0.0D, 0.0D, 0.0D },
{ 0.0D, -1.0D, 0.0D, 255.0D },
{ 0.0D, 0.0D, 1.0D, 0.0D },
};
// Identity.
double[][] matrix = {
{ 1.0D, 0.0D, 0.0D, 0.0D },
{ 0.0D, 1.0D, 0.0D, 0.0D },
{ 0.0D, 0.0D, 1.0D, 0.0D },
};
// Luminance stored into red band (3 band).
double[][] matrix = {
{ .114D, 0.587D, 0.299D, 0.0D },
{ .000D, 0.000D, 0.000D, 0.0D },
{ .000D, 0.000D, 0.000D, 0.0D }
};
// Luminance (single band output).
double[][] matrix = {
{ .114D, 0.587D, 0.299D, 0.0D }
};
// Create the ParameterBlock.
ParameterBlock pb = new ParameterBlock();
pb.addSource(src_image);
pb.add(matrix);
// Perform the band combine operation.
dst = (PlanarImage)JAI.create("bandcombine", pb, null);