This Program can be used to load and save .ppm images. A multiple of image filters can be applied to the images. Furthermore the program can create .ppm images from scratch and allow the user to draw a selection of geometry onto the image. The user can draw points, lines, rectangles and circles onto the image.
To run make sure that cmake is installed on the machine.
In ppm-processing/
mkdir build
cd build
cmake ..
make
./image_processor
To create an image use the ImageGenerator
class. The class has two constructors:
// creates an empty image
ImageGenerator image_generator = ImageGenerator();
// loads an image from a ppm file given the path
ImageGenerator image_generator = ImageGenerator(std::string <path_to_file>);
Optionally a .ppm image can be loaded into the image generator using the following code:
image_generator.read_image_from_file(std::string <path_to_file>);
To save the edited image to a .ppm file use the following code:
image_generator.save_image_to_file(std::string <path_to_file>);
The images are stored as a two dimensional std::vector< std::vector<Triple> >
where a Triple
is a data structure storing three integer values. These are used to represent the color channel values of each of the pixels in the image. As we are using vectors to store the pixels we can access the pixels of an image via the following code:
Triple c = image_generator.get_image()[y][x];
In this example c
is the pixel in row y and column x, where row 0 is at the bottom of the image and column 0 is at the left of the image.
To loop through every pixel of the image use the following code:
for (size_t i = 0; i < image_generator.get_height(); i++) {
for (size_t j = 0; j < image_generator.get_width(); j++) {
Triple pix = image_generator.get_image()[i][j];
}
}
Note that image_generator.get_image()
returns the actual vector storing the image and the image can be edited via this getter function.
The following filters can be applied to a loaded .ppm images. The examples have been applied to this original picture:
This filter adds a color to every pixel in the image functionally applying a color filter to the entire image.
image_generator.apply_color_filter(Triple filter);
This filter inverts the color of every pixel in the image.
image_generator.apply_inverted_filter(Triple filter);
This filter averages the three color channels of every pixel in the image. This turns the image into a grayscale version of the image.
image_generator.apply_grayscale_filter(Triple filter);
Note that for any geometry providing points outside of the image dimensions will increase computation time as the program will compute points that are not displayed to the user. All geometry displayed however, fits the provided arguments.
The whole image can be filled with a solid color using the following code:
image_generator.fill_with_color(Triple color);
To draw a point onto the image use the following code:
image_generator.draw_point(Triple color, int x, int y, int thickness);
The x
and y
parameters determine the position of the point, while the thickness
parameter determines the width of the point.
To draw a line onto the image use the following code:
image_generator.draw_line(Triple color_a, Triple color_b, int x1, int y1, int x2, int y2, int thickness);
The x1
,y1
,x2
and y2
parameters determine the position of the points that the line connects, while the thickness
parameter determines the width of the point. The two colors color_a
and color_b
are the colors of the line at positions (x1,y1)
and (x2,y2)
respectively. The color of the line is interpolated between the two given colors. For monochrome lines provide the same color for both arguments.
To draw a rectangle onto the image use the following code:
image_generator.draw_rect(Triple color, int x1, int y1, int x2, int y2, int thickness, bool fill);
The x1
,y1
,x2
and y2
parameters determine the position of the points defining the two opposing edge points of the rectangle, while the thickness
parameter determines the width of the edge of the rectangle. The fill
parameter determines if the rectangle is filled (true) or empty (false). Note that the thickness
is set to 1 if the fill
parameter is set to true.
To draw a circle onto the image use the following code:
image_generator.draw_circle(Triple color, int x_c, int y_c, int r, int thickness, bool fill);
The x_c
and y_c
define the center of the circle while r
is the circle's radius. The thickness
parameter determines the width of the edge of the circle. The fill
parameter determines if the circle is filled (true) or empty (false). Note that the thickness
is set to 1 if the fill
parameter is set to true.
To draw a circle onto the image use the following code:
image_generator.draw_triangle(Triple color, int x1, int y1, int x2, int y2, int x3, int y3, int thickness, bool fill);
The x1
,y1
,x2
, y2
, x3
and y3
define the corners of the triangle. The thickness
parameter determines the width of the edge of the triangle. The fill
parameter determines if the triangle is filled (true) or empty (false). Note that the thickness
is set to 1 if the fill
parameter is set to true.