The goal of this assignment was to familiarize us with Unix, C language and working with images, such as reading and writing those images, as well as manipulating pixels inside of them.
1. Color Channels
In this task we were supposed to modify the for loop in the main program. I assigned zeros to every two of three color channels of the image, leaving just one to be at it's maximum value minus intensity:
So if it is red, that means that blue and green channels are zeros, etc.
2. Image Mask
Here I created a mask from a bluescreen image by looping over all pixels and checking which ones are blue:
If the above statement was right, the pixels were blue, I assigned 255 values to all the color channels (turning blue background into white), otherwise all the channels were assigned 0 value (turning the foreground figure black):
My outfit at the day of taking picture was not a lucky one (blue happened to be my favorite color =) ), but I think, despite that, it worked out pretty well.
3. Alpha Blending
My next step was to create an alpha blended image, which is taking my figure from the blue-screen image and placing it to the front of the background I choose. That was done using the mask created in the task 2. For every non-zero pixel (non-blue in the original image) in the mask, the pixel from the same position in the blue-screen image was taken, while the pixel of the background where the blue-screen would be got zero value. If you look at the formula below, alpha values were either 0 or 1, depending on values from the mask, so that either left or right part of the equation would negate leaving pixels of only one of the images to be displayed:
I also let user to input the offsets for dx, dy, so my figure could be moved to any position in the background.
So I took in the following images:
Giving dx, dy maximum possible values, I got myself in the clouds with sheep ears:
At last I decided to blend in some more clouds with conditional transparency sort of. The image happened to be mostly blue, so if the blue of a pixel was in the range of 50 to 255, I made it more transparent then for the ones out of range. That made the lighter parts be less transparent, which made them lighter, since the background was lighter, and the darker parts more transparent and darker.
The new image:
Here is how it turned out:
To get what I wanted I needed to play around a little to find what range works the best. So you can see the lighter parts like the line on the top and some pear-like shape in the middle, which makes me look like a jinn (or may be I am just imagining things :) ). So, yep, the lighter ones have less transparency.
So this project, huh, really I learned a whole bunch. Firstly, some about memory management and how images are stored and how to get inside of them. Secondly, I got to learn some basic C things. How to get user input for example, or how to read in an integer from the user input. While creating new files and adding their references to the makefile, at first, I was getting a lot of errors and had no clue what was going on. But after some wobbling around it all came together and I now have an idea of the whole making structure, how the process goes step by step.
Here are some random realizations I wanted to note down:
- A lot of work in C, I found, is about not letting C go out and rewrite stuff on its own.
- Also I attempted to make some of my code more compact and sort of failed, cause my resulting generalized code would be even larger than the previous. But it is fine. I am sure after I get some experience in C, it'll get better. So here is a space for growth. :)
- Once again, C is hard compare, for example, to Python, where you don't think as much about memory management. But then, trying same graphic transformations on images with both, I can clearly see how faster C is.