Modifying Images with tint and filter¶
In these notes you will learn:
- How to change the transparency of an image using the
tint
function. - How to modify the entire screen using the
filter
function. - How to modify individual images by calling their
filter
function. - How to copy an image using
get()
.
Introduction¶
The topic of image processing is a big and important one. Almost any software that deals with images does some sort of image processing, such as:
- cropping or re-sizing images
- changing colors or brightness
- removing “noise”, such as dust due to a dirty lens
- applying special effects, such as converting to black and white, sharpening, or blurring the image
- finding faces
Here, we will only scratch the surface of image processing by looking at two
useful Processing functions: tint
and filter
.
The programs below use these images: kandinsky.jpg
, cat.jpg
, and
dog.jpg
. If you want to run the programs on your
computer, then add them to your program’s data
folder.
The tint Function¶
One of the easiest ways to modify an image is to use the tint
function.
Using tint
, we can do things like change an image’s transparency, or alter
its overall color.
We will start with the program from Using Images in Processing that displays an image:
PImage img;
void setup() {
// load the image file from the "data" folder
img = loadImage("kandinsky.jpg");
// set the window to be the same dimensions as the image
size(1098, 757);
}
void draw() {
// set the image's tint
tint(100, 0, 204); // bluish tint
// display the image so that its upper-left corner
// is on the upper-left corner of the screen
image(img, 0, 0);
}
For this program to work, you must have a file named “kandinsky.jpg” in a
folder named data
in your program’s folder.
Just before the image is drawn on the screen, we set the tint like this:
tint(100, 0, 204); // bluish tint
The RGB color (100, 0, 204) is a shade of blue, and so this gives the entire image a blue tint.
As you might imagine, changing the color you give to tint
changes the
overall coloring of the image, e.g.:
tint(221, 160, 221)
gives the image a “plum” colored tinttint(200, 200, 200)
gives the image a light-gray tinttint(0, 0, 0)
makes the entire image blacktint(255, 255, 255)
doesn’t change the image color at all
Changing Transparency with Tint¶
The tint
function can also be used to set an image’s transparency. For
example, consider this modified version of the above image-displaying
program:
PImage img;
void setup() {
// load the image file from the "data" folder
img = loadImage("kandinsky.jpg");
// set the window to be the same dimensions as the image
size(1098, 757);
}
void draw() {
background(img);
// set a bluish tint, and a transparency level of 126
tint(0, 153, 204, 126);
image(img, mouseX, mouseY);
}
This program draws img
twice: once as an untinted background, and then a
tinted version at the mouse pointer. By moving the mouse around you can see
the image really is transparent, i.e. you can see the background image behind
it.
If you want to change an image’s transparency without changing its color, then use a white tint, e.g.:
tint(255, 255, 255, 126); // change transparency only
The filter Function¶
Another easy way to modify the entire screen is to use the filter
function. Consider this version of our standard image-drawing program:
PImage img;
void setup() {
// load the image file from the "data" folder
img = loadImage("kandinsky.jpg");
// set the window to be the same dimensions as the image
size(1098, 757);
}
void draw() {
image(img, 0, 0);
filter(THRESHOLD, 0.5);
//filter(GRAY);
//filter(INVERT);
//filter(POSTERIZE, 4);
//filter(BLUR, 6);
//filter(ERODE);
//filter(DILATE);
}
We’ve added a number of calls to filter
, all but the first commented-out.
The statement filter(THRESHOLD)
converts the image to black-and-white. It
does this, essentially, by calculating the brightness of each pixel in the
image and converting the brighter ones to white, and the darker ones to black.
It uses a brightness scale of 0.0 (minimum brightness, i.e. black) to 1.0
(maximum brightness, i.e. white). The 0.5 is called the threshold value,
and you can get different results by changing it to other values in the range
0.0 to 1.0.
The comment-out filter
statements work as follows:
filter(GRAY)
converts all of the image’s color to shades of gray, i.e. grayscale.filter(INVERT)
sets each pixel in the image to its inverse color.filter(POSTERIZE, 4)
limits the red, green, and blue components of each pixel to only 4 colors.filter(BLUE, 6)
blurs the image. Higher values result in more blur.filter(ERODE)
reduce light areas.filter(DILATE)
increases light areas.
You comment/uncomment any combination of these filter calls to get a variety different special effects.
Note
In fact, with 7 different filter
statements, there are exactly
\(2^7=128\) different ways to turn them on/off.
Note that applying a filter to an image it must process every pixel of the image. So if you apply a lot of filters to a big image you might notice some delays.
Processing also lets you use shaders with filters, although it is a relatively advanced topic that we won’t go into here. If you are curious about this, this tutorial is a good place to start.
Filtering Individual Images¶
The filter function in the previous section is applied to the entire screen.
If, instead, you want to apply a filter to a particular PImage
, you can do
that as follows:
PImage cat;
PImage dog;
void setup() {
// load the image files from the "data" folder
cat = loadImage("cat.jpg"); // 220 x 210
dog = loadImage("dog.jpg"); // 240 x 180
// apply some special effects
cat.filter(POSTERIZE, 4);
dog.filter(GRAY);
// set the window to be big enough to display both images
// side-by-side
size(220 + 240, 210);
}
void draw() {
// display the images side-by-side
image(cat, 0, 0);
image(dog, cat.width, 0);
}
This program uses two different PImage
objects, cat
and dog
. They
both load their own file, and then we call the filter function on the objects
to apply a special effect.
To make the filter commands apply to just one image, we write, for instance,
dog.filter(GRAY)
. If we had written filter(GRAY)
instead, the entire
screen, including both images, would have been grayscale.
Copying an Entire Image¶
Suppose you want to display two copies of the same image. While you could call
loadImage
twice, that’s inefficient. Instead, PImage
objects let you
make copies using the get()
function like this:
PImage original;
PImage duplicate;
void setup() {
original = loadImage("cat.jpg");
duplicate = original.get(); // makes a new copy of original
// ...
}
There are now two different copies of the “cat.jpg” in the program’s memory:
one referred to by original
, and the other referred to by duplicate
.
Note
PImage
objects also have a function called copy that you can use to
make a copy of any sub-rectangle of an image. We could have used copy
here, but get()
is less typing.
Questions¶
What are three different things an image processing program might do to an image?
Describe, in English, how the following tints would change the color of an image:
tint(0, 0, 0)
tint(255, 255, 255)
tint(100, 0, 0)
tint(200, 0, 0)
Write the tint statement that would set the transparency level of an image to 10 without changing its color.
Explain this statement in English:
filter(THRESHOLD, 0.5);
Write the
filter
statements you would use to create a blurry grayscale version of a color image.
Programming Questions¶
- Modify the last program in the notes that shows the cat and dog pictures so that the instead of being drawn side-by-side, the cat is drawn on top of the dog. The two images not overlap.
- Modify the last program in the notes that shows the cat and dog pictures so
that the image of the cat is shown twice. Call
loadImage
exactly once, and then useget()
to copy it.