Graphics With Processing III

From CompSciWiki
Jump to: navigation, search

COMP 1010 Home > Back to Extra Labs

Introduction

This lab will involve some simple image processing tasks in Processing. We will see how to load images for display in a Processing window, then we will manipulate the image. Finally we will save the finished image.

Image by Graeme Peters

Step 1: Loading and displaying the image

Create a new Sketch called Lab3 and save it. Locate the folder where the sketch is stored and place this image file inside. The setup function should look like this:

 PImage img;

void setup()
{
  img = loadImage("Stairs3.jpg");
  size(480,320);
  frameRate(10);
} 

The PImage object 'img' will hold our image file while we are working on it. The loadImage() function takes the name of the image file that we are loading in. It will load .gif, .jpg, .tga, and .png files. Note that the image must be in the same directory with the sketch.

Next we will draw the image in our sketch window. Create a draw function like this:

 void draw()
{
  background(0);
  image(img,0,0);
} 

Here we are just colouring the background black and then drawing the image in the top left corner - (0, 0). You can now run the sketch. The window should contain the picture of the green stairs from the Wiki home page.


Step 2: Brightness adjustment

We will now create several functions that will allow us to adjust the brightness of our image. First we will create the bright() function.

 void bright(int val)
{
  img.loadPixels();
  color temp;
  
  for(int i=0; i < img.pixels.length; i++)
  {
    img.pixels[i] = color(red(img.pixels[i]) + val,
                          green(img.pixels[i]) + val,
                          blue(img.pixels[i]) + val);
  }
  
  img.updatePixels();
} 

This function loops through every pixel in the image and changes its brightness. It does this by changing each colour of the pixels by the same amount. Before you access the img.pixels[] array you must always call loadPixels. This alerts Processing that are going to be reading and possibly changing the array. Likewise, after you are done modifying the pixel data you must call updatePixels(). This lets the runtime know that you are done with the array and it will copy the data to the active image.

Next we will create a keyPressed() function. This built in function activates whenever a key is pressed. The 'key' system variable allows you to tell what key was pressed. Your keyPressed() should look like so:

 void keyPressed()
{
  if(key == 'b')
  //lower brightness
  bright(-10);
  
  else if(key == 'B')
  //increase brightness
  bright(10);
} 

Here we are using the 'b' key to change the brightness of the image; a lowercase 'b' will lower the brightness and an uppercase 'B' will increase it.

You can now run the sketch and test your brightness function.


Step 3: Inverting the Image

Now we are going to create a function that inverts the colours of the image. Call this function invert(). Invert does not need to accept any parameters. The function will look similar to bright() (you can copy, paste, and rename it) except for the line where the colours are changed. The inversion function (since the colour values are between 0 and 255) will look like this:

 ...
    img.pixels[i] = color(255 - red(img.pixels[i]),
                          255 - green(img.pixels[i]),
                          255 - blue(img.pixels[i]));
... 

Now you can add a few lines into your keyPressed function to enable your inversion routine.

 ...
  else if(key == 'i')
  //invert image colours
  invert();
... 

Run the sketch to make sure the colours get inverted.


Step 4: Changing The Image Contrast

The last image manipulation we will be performing is changing the contrast of the image. The formula for the contrast adjustment is:

 value = (value - 0.5) * (tan ((contrast + 1) * PI/4) ) + 0.5; 

Say you are increasing the contrast; this formula would adjust the brightness higher if the pixel were brighter than half the max brightness value and lower if the pixel is darker than half of the max. This has the effect of setting the darker and light pixels farther apart in relative brightness.

The contrast() function will again look similar to brightness(). The line that manipulates the pixels should look like this:

 img.pixels[i] = color(((red(img.pixels[i])/255.0 - 0.5) * (tan ((val + 1) * PI/4)) + 0.5)*255,
                          ((green(img.pixels[i])/255.0 - 0.5) * (tan ((val + 1) * PI/4)) + 0.5)*255,
                          ((blue(img.pixels[i])/255.0 - 0.5) * (tan ((val + 1) * PI/4)) + 0.5)*255); 

We must change the value from a (0-255) range to a (0-1.0) range here for this formula to work. The contrast function should take a float that determines the value of the contrast change from -1.0 to 1.0. All you need to do now is add in the lines in keyPressed() (use 'c' and 'C' to adjust the contrast -0.1 and 0.1) and run the sketch.


Step 5: Reloading The Original Image/Saving Your Edited Image

We will now add the ability to reload the original image, and save the edited image. Add these cases in your keyPressed():

 ...
  else if(key == 'o')
  //reload original image
  img = loadImage("Stairs3.jpg");
  
  else if(key == 's')
  //save the altered image file
  img.save("newimage.jpg");
... 

The first entry will reload the original image from the file and reset all of the changes that have been done. The second one adds the functionality to save the edited image. The save function accepts the name of the new file as a parameter.

Your image editing application is now complete. The full source is available here. For an extra challenge you could try adding zooming, panning, cropping and GrayScale conversion. Have fun!