For this project, we were adjusting the color levels in images. By changing the red, green, and blue values of an image selectively, many different effects can be achieved, and the changed images can be put side-by-side to make a Warhol-style collage. We also changed the background of our pictures of ourselves to a different color; personally, I chose to go from green to white.

Our first task was to create a program that would take in an image then make a copy of it and set it next to it, showing them side-by-side. The code is shown above, with the result below.

As one can see, the code loops over the image, gets each pixel's RGB values, then places the same pixels next to and relative to the image, effectively creating two identical images side-by-side. The image also needed to be run through a program that tested for user input on the command line to see what image file to use.

The second task was to create three more filters for the images. I made a filter that darkens the image, a filter that makes it grayscale, and a filter that makes it green-scale. For the darken function, I made the program find the RGB values of each pixel in the image using pmap.getWidth(), with "pmap" being the selected image, which is typed into the command line when calling the program. For the grayscale function, I decided on three thresholds as pictured below: 90, 150, and 255. Depending on how high the intensity of the pixel (or how bright it is) was, it would be assigned a different shade of gray, denoted by colors 1-3. The green scale filter was similarly made, except it had many more thresholds and colors; for example, if the intensity of a pixel was less than or equal to threshold one, which was 10, it would be reassigned the RGB value of ??(25,25,25). After applying each filter, I saved the output image under a new name, e.g. "greenzena.ppm" for my green-scale filtered image of myself.

The collage below demonstrates all of my filters and is also the result of calling my warhol.py program. This was the third task -- to make a collage out of one image filtered in four different ways and placed together in one window. This meant I needed to use the placePixmap function from before, choosing the coordinates of the images for where in the bigger image, or the canvas, it would go. For the given image, I first needed to make 4 clones, which means I had to assign 4 variables to map.clone(); for example, map1=pmap.clone() creates copy of the image and stores it as "map1." Next, I needed to apply the filters to each map, e.g. filter.swapRedBlue(map1) -- this alters map1 by applying the swapRedBlue filter to it. After that, I created the canvas using canvas=gs.Pixmap(2*pmap.getWidth(),2*pmap.getHeight()). In effect, this creates a big blank image that is twice the width and height of the given image, which will allow us to ?fit the image in four times. Lastly, I placed each map using the placePixmap function. For instance, _placePixmap(canvas,map3,pmap.getWidth(),0) _puts map3 into the canvas at location ([width of the image], 0), starting from the upper-left corner. This is the grayscale image in the collage.

For the last task, I located all of the green screen background pixels from my picture and recolored them white. This was basically done by just looping over the picture using the aforementioned for loops and testing how green they were. In this case, I used if g>=2*r and g>b and g-r>55:, meaning if the pixel's green value is more than twice as large as its red and more than its blue and its green minus red is over 55, then (this is the part that makes it white) use pmap.setPixel(x,y,(255,255,255)) to set the pixel color at (x,y) to white (which has an RGB value of (255,255,255)).

Extension 3 was similar to the function from the last task, which located all the green pixels and replaced them. This time, however, instead of replacing the colors, I did nothing with the green pixels (using an empty if statement; I just has "pass" under it) but instead focused on the non-green pixels: namely, me. This was done using an "else:" statement as a follow-up to the if statement. Basically, if the pixel is green, do nothing -- otherwise, do something. In this case, that "something" was to set the pixels in the destination image to take the values of those taken from my source picture. And since two images were involved -- that of me and that of the background -- I had to account for command-line input by the user in indexes two and three. For instance, typing "ext3.py Zenapicture.ppg extbg.ppg" into the command line after calling python to open would set the foreground picture to mine, which is given in index 1 of the argv list, and the background one to "extbg.ppg", which is in index 2 of the argv list. The result is pictured below:

Lastly, I undertook extension 4, which was just to make the user able to generate multiple collages by inputting multiple image files into the command line. This was accomplished in almost the same way as the warhol program. I called the collages to be made three times, using the command-line input following the indexes in the argv list. Depending on the index and the filename, the end result would be different. For example, calling main(sys.arg[2]) takes the file specified in index 2 and makes a collage out of it. If I just ran through all these images though, only the last one would be saved, meaning I had to come up with a way to give them separate names. I took in the name of the file as the changing variable for each time the collage was made, and used canvas.save("canvas"+str(argv)) to string together the string "canvas" and the name of the original image. In the end, a picture with the same name as it started with, except with "canvas" in front, was created. This was repeated for each picture. The commands below called 3 collages to be created, which were then viewed to make sure they worked properly...

...and they did!

Overall, this project taught me a lot about how to manipulate RGB values in pictures to change their appearances. I also figured out how to have empty if statements -- you would just use "pass" -- which is very useful for times when you have selected the exact opposite of what you need. Additionally, I became more comfortable working with user input from the terminal.