In this chapter we'l l discuss how color is handled in Jitter. We'll focus on the numerical representation of a color, and conversely the visualization of numbers as color. A thorough discussion of color theory—knowledge of how light and matter produce our sensation of color—is well beyond the scope of this tutorial, as is a discussion of the many ways to represent color information digitally. If you wish to learn more about color theory and/or digital representations of color, you can find some other sources of information listed in the Bibliography.
Here we present one method of representing color and how that representation is handled in Jitter matrices.
Color Components: RGB
It's possible to produce any desired color by blending three colors of light—red, green, and blue—each with its own intensity. This is known as additive synthesis—generating a color by adding unique amounts of three "primary" colors of light. (The opposite of this is subtractive synthesis: mixing colored pigments, such as paint, which absorb certain colors of light and reflect the rest.) Thus, we can describe any colored light in terms of its intensity at the three frequencies that correspond to the specific colors red, green, and blue.
In Jitter, this is the most common way to describe a color: as a combination of exact intensities of red, green, and blue. For each pixel of an image—be it a video, a picture, or any other 2D matrix—we need at least three values, one for each of the three basic colors. Therefore, for onscreen color images, we most commonly use a 2D matrix with at least three planes.
The Alpha Channel
A fourth plane is often useful for what is known as the alpha channel—a channel that stores information about how transparent a pixel should be when overlaid on another image. We won't deal with the alpha channel specifically in this tutorial chapter, but we mention it here because its inclusion is standard in most Jitter objects that deal specifically with representations of color. In most cases, the alpha channel is stored in the first plane (which is plane 0, because planes of a matrix are numbered starting from 0), and the RGB values are in planes 1, 2, and 3.
Color Data: char, long, or float
It's fairly standard in computer applications to use 8 bits of information per basic color value. 8 bits gives us the ability to express 256 (2 to the 8th power) different values. This means that if we use 8 bits for red, 8 for green, and 8 for blue, we can express 16,777,216 (224
) different colors. That's a sufficient variety of colors to cover pretty thoroughly all the gradations we're able to distinguish.
So, if we only need 8 bits of resolution to represent each basic color value, that means that the 8-bit char data type is sufficient to represent the value in each plane of a four-plane matrix of color information. We could use the long, float32, or float64 data type, and Jitter will certainly let us do that, but we'd be using much larger data types than we really need. Since a full-frame video image can contain a very large number of pixels (a 640x480 image has 307,200 pixels), it often makes most sense—in order to conserve memory and speed up processing—to use the char data type.
When a matrix contains 8-bit char
data, we can think of those 8 bits as representing numbers from 0 to 255, or we can think of them as representing gradations between 0 and 1 (i.e. as a fixed-point fractional number). When a Jitter object containing char
data receives numerical values from other Max objects, it usually expects to receive them in the form of f s in the range 0 to 1. It will make the internal calculations necessary to convert a f from Max into the proper char
value. (There are a few exceptions to this rule. For example the jit.op
object can accept either s in the range 0-1 or
s in the range 0-255 in its right inlet, as demonstrated in Tutorial 3.) For more on the use of the char
data type in Jitter matrices, see the manual chapter "What's a Matrix?".
At the top of the patch you are given two different colorful source materials. One is a video of an arcade game, and the other is the standard set of color bars for used for video calibration. You can choose to see one or the other by turning on the one of the metro
objects (to repeatedly the object containing the matrix you want to see).
View a video or a still image
• Click on the toggle marked "Show movie" above the metro
object to view the video.
This example patch breaks up a 4-plane matrix of color information into four 1-plane matrices, in order to allow you to see—and modify—each plane individually. We achieve this with an object called jit.unpack
. Just as the Max object unpack
breaks a list into individual numbers, jit.unpack
breaks a multi-plane matrix into individual 1-plane matrices. You can type in an argument to tell jit.unpack
how many planes to expect in the incoming matrix, but by default it expects four planes since that's the norm for color data. We're interested in seeing the contents of the red, green, and blue planes, so we send planes 1, 2 and 3 to individual jit.pwindow
objects. In this case we're not interested in the alpha channel, so we don't bother to display plane 0.
Unpacking a multi-plane matrix as single-plane matrices
Here you can see the content of each color plane, in the form of three monochrome images. The lighter pixels indicate higher values for that color. By sending each matrix to a jit.op
object, we obtain individual control over the strength of each color, and can alter the color balance. We then send the individual (altered) matrices to a jit.pack
object to recombine them as a 4-plane matrix, for display in the jit.pwindow
• Try, for example, reducing the intensity of green and blue to 0.12, to create a redder image.
Reducing the intensity of certain colors to alter the color balance
To demonstrate another color trick, we've sent each color plane through a gate
object, so that each matrix can be routed to a different inlet (color plane) of jit.pack
. In this way, the meaning of each plane can be reassigned, and we can try all the permutations of possible color assignments by choosing a setting from the coll
object on the left side of the patch.
• Drag on the number
box marked "Rotate RGB planes" to try different reassignments of the three color planes. (Note that plane 0 is sent directly through from jit.unpack
; it's the message coming in the left inlet of jit.pack
that triggers output of the matrix to the jit.pwindow
.) If you choose item 3 in the coll
, you get the result shown below.
The individual color planes are reassigned; the red and green planes are swapped here.
The example above shows the original green and blue planes reduced by a factor of 0.12, and the gate
s are set so that the red and green planes are swapped when they're sent to jit.pack
, resulting in an image with more green in it. The coll
object contains all the possible permutations of assignments of the RGB planes.
• Double-click on the coll
object to see its contents.
0, 0 0 0;
1, 1 2 3;
2, 1 3 2;
3, 2 1 3;
4, 2 3 1;
5, 3 1 2;
6, 3 2 1;
Permutations of RGB plane assignments
The elements in the coll
are unpacked and sent to assign the outlets of the three gate
objects. The number sent into coll
is also sent to a umenu
(in Label mode) to show the color rotation in words—in this case "Green-Red-Blue".
coming out of the
For one more exercise in color modification, we've made an automated process for continually changing the scaling and rotation of colors.
• Click on the toggle
marked "Automate color changes". The scaling factors for the three color planes all change continually. Double-click on the patcher
object to see the contents of the subpatch.
The subpatch uses line
objects to send values that progress from 0.5 to 1 for each of the color scaling factors. The red factor changes over the course of 3 seconds, green in 4 seconds, and blue every 5 seconds. (The three line
objects thus come into sync once every 60 seconds.) Every 60 seconds, a new color rotation is selected by the metro
• Close the [colorgames]
subpatch window. You can try all of these same color modifications on different source material. Click on the toggle
marked "Show movie" to stop the metro
. (Note that we also use this toggle
to start and stop the movie playing in the jit.qt.movie
object. There's no reason to keep the movie playing if we're not even watching it.) Now click on the toggle
marked "Show colorbars" to display the colorbars. Experiment with changing the scaling factors and rotation on this image.
When a jit.window
receives a single-plane 2D matrix, it displays the values as a monochrome (greyscale) image. When it receives a 4-plane 2D matrix, it interprets the planes as alpha, red, green, and blue values, and displays the resulting colors accordingly. This ARGB representation in a 4-plane matrix is the most common way of representing colors in Jitter.
Because each of the basic colors only requires 8 bits of precision to represent its full range, it's common in Jitter to use the char
data type for color data. Thus, most of the QuickTime-related objects (such as jit.qt.movie
) and many of the objects specifically designed for manipulating colors (such as jit.brcosa
, which are demonstrated in later tutorial chapters) expect to receive 4-plane 2D matrices of char
data. (Many other objects adapt readily to other types of data, though. Check the reference documentation for the object in question when you're in doubt.) You can think of the char
data as representing values 0 to 255, or you can think of them as representing fractional values from 0 to 1. Most of the time, objects that contain char
data expect to receive numerical values from other Max objects specified as s in the range 0 to 1.
object splits a multi-plane matrix into individual single-plane matrices. The jit.pack
object combines single-plane matrices into a single multi-plane matrix. By treating each plane spearately, you can control the color balance of an image, or even reassign the meaning of the individual planes.
Store and edit a collection of different messages
Count the bang messages received, output the count
The Jitter Matrix!
Apply binary or unary operators
Make a multiplane matrix out of single plane matrices
Play or edit a QuickTime movie
Make multiple single plane matrices out of a multiplane matrix
Output numbers in a ramp from one value to another
Output a bang message at regular intervals