Lecture 37 (Sherriff & Tychonievich) - Images Intro

Lecture Date: Wednesday, April 15

For the next few days, we are going to look at the algorithms behind some basic image manipulation.

First thing’s first: we need to know how to load in a picture into our Java programs. We will be using a class called Picture that was written at Georgia Tech specifically for use in CS 1 courses.

To get started, download this project and import it into Eclipse: ImageManipulation.zip

If the project doesn’t work for you, here’s a jar file that you can add to your build path (ask a TA for assistance) along with some pictures to work with:

This project has the Picture class preloaded in it, along with some very basic sample code with three images you can play with.

Drawing with Pixels

We started our programming journey by learning to draw pictures with the Turtle. But what exactly is a “picture” in the context of a computer program?

In effect, it’s a 2D array of pixels.

Well, what’s a pixel?

A pixel is the smallest display element of a picture. It could be dots on your monitor or TV, or how small an ink jet printer can put a dot on your paper (although we still typically call that “dots”). The pixel specifies what color (or components of colors) should be used to display that particular location in accordance with a color model. “Pixel” is short for “picture element.”

Printers (and paints and crayons…) use a subtractive color model. That is, as you add more color (paint), more light is absorbed. Thus, adding in all the colors makes the color black, as shown in the CMYK model below.

CMYK

However, computer monitors (and all forms of light, like stage lighting) use an additive color model, like RGB.

RGB

So, as we add more and more colored lights, we get closer to white, not black!

In RGB, each of the three primary colors (Red, Green, and Blue) can have a value from 0 to 255. This allows for 16,777,216 colors (in theory)!

For example, (255,0,0) is red. But (128,0,0) is also red. It’s just not a “saturated” or bright as the first red. If all three values of , G, and B are the same, you get some shade of gray (or white or black).

Many pixels also have a fourth value - alpha. That tells the pixel how much to blend with any images behind the one that is currently “on top” and about to be drawn.

How many pixels?

It’s a big question when you buy a new camera. “How many megapixels is this thing?”

For reference:

  • An old, standard TV is about 852 x 480 = 400K pixels
  • A 1080p HD TV is 1920 x 1080 = 2M pixels
  • Many laptop monitors are 1680 x 1050 pixels
  • A “retina” MacBook has 2880 x 1800 pixels
  • An 8 megapixel camera has 3264 x 2448 pixels

So, why does resolution really matter if the monitors can’t display all that information?

Picture

The Picture class we will use has a Pixel class associated with it. Each Pixel has a Color associated with it, and we can get and set the RGB value of that Color in the Pixel.

Today, we’ll look at the Picture API and do some very basic grabbing of pixels and printing their RGB values to the screen.

Example Code

Here are some example algorithms:

Example Image Algorithms
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Picture pict1 = pictureList.get(0);
pict1.show();

// flip picture on y axis
Picture flipped = new Picture(pict1.getWidth(), pict1.getHeight());
for (int j = 0; j < pict1.getHeight(); j++) {
  for (int i = 0; i < pict1.getWidth(); i++) {
      Pixel source = pict1.getPixel(i, j);
      Pixel destination = flipped.getPixel(pict1.getWidth() - 1 - i,
              j);
      destination.setColor(source.getColor());
  }
}
flipped.show();

// rotate picture 90 degrees clockwise
Picture flipped2 = new Picture(pict1.getHeight(), pict1.getWidth());
for (int j = 0; j < pict1.getHeight(); j++) {
  for (int i = 0; i < pict1.getWidth(); i++) {
      Pixel source = pict1.getPixel(i, j);
      Pixel destination = flipped2.getPixel(
              pict1.getHeight() - 1 - j, pict1.getWidth() - 1 - i);
      destination.setColor(source.getColor());
  }
}
flipped2.show();

// get negative of picture
Picture negative = new Picture(pict1.getWidth(), pict1.getHeight());
for (int j = 0; j < pict1.getHeight(); j++) {
  for (int i = 0; i < pict1.getWidth(); i++) {
      Pixel source = pict1.getPixel(i, j);
      Pixel destination = negative.getPixel(i,j);
      Color c = new Color(255-source.getRed(), 255-source.getGreen(), 255-source.getBlue());
      destination.setColor(c);
  }
}
negative.show();

Sherriff:

Tychonievich: