Commit 6917ef16 authored by Rachel Wil Sha Singh's avatar Rachel Wil Sha Singh 💬
Browse files

2018 notes

parent 75698737
#include "Image.hpp"
#include <fstream>
#include <iostream>
#include <exception>
using namespace std;
void PpmImage::LoadImage( const string& filename )
{
cout << "Loading image from \"" << filename << "\"...";
throw runtime_error( "Method not implemented!" );
cout << "SUCCESS" << endl;
}
void PpmImage::SaveImage( const string& filename )
{
cout << "Saving image to \"" << filename << "\"...";
throw runtime_error( "Method not implemented!" );
cout << "SUCCESS" << endl;
}
void PpmImage::ApplyFilter1()
{
cout << "Applying filter 1...";
throw runtime_error( "Method not implemented!" );
cout << "SUCCESS" << endl;
}
void PpmImage::ApplyFilter2()
{
cout << "Applying filter 2...";
throw runtime_error( "Method not implemented!" );
cout << "SUCCESS" << endl;
}
#ifndef _IMAGE_HPP
#define _IMAGE_HPP
#include <string>
using namespace std;
const int IMAGE_WIDTH = 300;
const int IMAGE_HEIGHT = 300;
struct Pixel
{
int r, g, b;
};
class PpmImage
{
public:
void LoadImage( const string& filename );
void SaveImage( const string& filename );
void ApplyFilter1();
void ApplyFilter2();
private:
int m_colorDepth;
Pixel m_pixels[IMAGE_WIDTH][IMAGE_HEIGHT];
};
#endif
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_project_file>
<FileVersion major="1" minor="6" />
<Project>
<Option title="Project1 - Image Manipulation" />
<Option pch_mode="2" />
<Option compiler="gcc" />
<Build>
<Target title="Debug">
<Option output="bin/Debug/Project1 - Image Manipulation" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Debug/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-g" />
</Compiler>
</Target>
<Target title="Release">
<Option output="bin/Release/Project1 - Image Manipulation" prefix_auto="1" extension_auto="1" />
<Option object_output="obj/Release/" />
<Option type="1" />
<Option compiler="gcc" />
<Compiler>
<Add option="-O2" />
</Compiler>
<Linker>
<Add option="-s" />
</Linker>
</Target>
</Build>
<Compiler>
<Add option="-Wall" />
</Compiler>
<Unit filename="Image.cpp" />
<Unit filename="Image.hpp" />
<Unit filename="main.cpp" />
<Extensions>
<code_completion />
<debugger />
</Extensions>
</Project>
</CodeBlocks_project_file>
# depslib dependency file v1.0
1599001555 source:/home/wilsha/TEACHING/PRIVATE/cs-235-object-oriented-programming-using-cpp/2020/Projects/Project1/Project1 - Image Manipulation/main.cpp
"Image.hpp"
<iostream>
<string>
1599000827 /home/wilsha/TEACHING/PRIVATE/cs-235-object-oriented-programming-using-cpp/2020/Projects/Project1/Project1 - Image Manipulation/Image.hpp
<string>
1599000823 source:/home/wilsha/TEACHING/PRIVATE/cs-235-object-oriented-programming-using-cpp/2020/Projects/Project1/Project1 - Image Manipulation/Image.cpp
"Image.hpp"
<fstream>
<iostream>
1599001555 source:/home/wilsha/TEACHING/PRIVATE/cs-235-object-oriented-programming-using-cpp/2020/Projects/Project1/Project1 - Image Manipulation - Starter/main.cpp
"Image.hpp"
<iostream>
<string>
1599000827 /home/wilsha/TEACHING/PRIVATE/cs-235-object-oriented-programming-using-cpp/2020/Projects/Project1/Project1 - Image Manipulation - Starter/Image.hpp
<string>
<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<CodeBlocks_layout_file>
<FileVersion major="1" minor="0" />
<ActiveTarget name="Debug" />
<File name="main.cpp" open="0" top="0" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="267" topLine="0" />
</Cursor>
</File>
<File name="Image.cpp" open="1" top="1" tabpos="1" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="305" topLine="0" />
</Cursor>
</File>
<File name="Image.hpp" open="0" top="0" tabpos="2" split="0" active="1" splitpos="0" zoom_1="0" zoom_2="0">
<Cursor>
<Cursor1 position="296" topLine="0" />
</Cursor>
</File>
</CodeBlocks_layout_file>
#include "Image.hpp"
#include <iostream>
#include <string>
using namespace std;
int main()
{
bool done = false;
string filename;
int filter;
while ( !done )
{
cout << "---------------------" << endl;
cout << "Work with image: ";
getline( cin, filename );
PpmImage image;
image.LoadImage( filename );
cout << "Which filter? ";
cin >> filter;
switch( filter )
{
case 1:
image.ApplyFilter1();
break;
case 2:
image.ApplyFilter2();
break;
}
cout << "Output filename: ";
cin.ignore();
getline( cin, filename );
image.SaveImage( filename );
}
return 0;
}
\documentclass[a4paper,12pt,oneside]{book}
\usepackage[utf8]{inputenc}
\newcommand{\laTopic} {Image Manipulation}
\newcommand{\laTitle} {CS 235/250 Project 1}
\newcounter{question}
\renewcommand{\chaptername}{Topic}
\usepackage{../../../rachwidgets}
\usepackage{../../../rachdiagrams}
\title{}
\author{Rachel Singh}
\date{\today}
\pagestyle{fancy}
\fancyhf{}
\lhead{\laTopic \ / \laTitle}
\chead{}
\rhead{\thepage}
\rfoot{\tiny \thepage\ of \pageref{LastPage}}
\lfoot{\tiny Rachel Singh, last updated \today}
\renewcommand{\headrulewidth}{2pt}
\renewcommand{\footrulewidth}{1pt}
\begin{document}
\setcounter{chapter}{1}
\chapter*{Project 1: Image Manipulation}
\begin{center}
\includegraphics[width=8cm]{project1-results.jpg}
\end{center}
\section{Assignment info}
\begin{itemize}
\item Once finished with the project, upload any source files for your project - .hpp, .h, and/or .cpp.
\textbf{Please don't zip your code.}
\item This project is \textbf{ \underline{solo effort} } - you can ask the instructor for help,
but otherwise should be working on this project solo. Don't give code to or receive code from
other people or locations.
\item This project is meant as review of CS 200 topics. In particular, it covers
classes, file I/O, and 2D arrays.
\item If you happen to be enrolled in my \textbf{CS 235} and \textbf{CS 250} courses
at the same time this semester, you only need to do this project once (just
submit the same files in each class).
\end{itemize}
\tableofcontents
\newpage
\section{Software needed}
We will be working with .ppm image files. You may need to use
something besides the default graphics tool on your computer,
such as Photoshop or GIMP or Glimpse to open it.
If you don't currently have a specialized image editor,
Glimpse is free and cross-platform and will be sufficient:
\begin{center}
https://glimpse-editor.github.io/
\end{center}
If you decide to create your own images to use in this assignment,
make sure it's set to 300x300 pixels (I've hard-coded the array
to be this size, though you can update \texttt{IMAGE\_WIDTH}
and \texttt{IMAGE\_HEIGHT} if you'd like), and export as a .ppm
file, using the ASCII format (not raw format).
\section{Project overview}
Make sure to download the starter code off Canvas, or copy
the starter code (in the Appendix of this document) in source files
on your computer. You will have three files:
main.cpp, Image.hpp, and Image.cpp.
\begin{hint}{Why ``.hpp'' instead of ``.h''?}
Technically, .h is a C header file. Some libraries that
are built on top of C++ specifically (such as SFML) use
the .hpp path suffix to make it clear that \textit{it is C++},
not C. That's what I tend to use as well. I just like the consistency.
\end{hint}
\paragraph{Image.hpp:}
The class declaration is already created in this file.
\begin{lstlisting}[style=code]
const int IMAGE_WIDTH = 300;
const int IMAGE_HEIGHT = 300;
struct Pixel
{
int r, g, b;
};
class PpmImage
{
public:
void LoadImage( const string& filename );
void SaveImage( const string& filename );
void ApplyFilter1();
void ApplyFilter2();
private:
int m_colorDepth;
Pixel m_pixels[IMAGE_WIDTH][IMAGE_HEIGHT];
};
\end{lstlisting}
We are going to be loading an image format that is just a
plaintext file full of pixel values, called a ppm file.
(See https://en.wikipedia.org/wiki/Netpbm for specifics)
You will be implementing the \textbf{LoadImage},
\textbf{SaveImage}, and \textbf{ApplyFilter} methods.
You can also add additional ApplyFilter methods if you'd like.
\paragraph{main.cpp:}
Main is already implemented, though you can add additional
cases to the switch statemnet if you end up adding more filters.
~\\
When you run the program, you will enter in a filename and type
in a number for a filter to apply, then type in the filename
to save the modified version as.
\begin{lstlisting}[style=output]
Work with image: bunny.ppm
Loading image from "bunny.ppm"...SUCCESS
Which filter? 1
Applying filter 1...SUCCESS
Output filename: bunny2.ppm
Saving image to "bunny2.ppm"...SUCCESS
---------------------
\end{lstlisting}
If you downloaded the starter files off Canvas there are already
a few .ppm files in there. You can open these in a photo editor
like Photoshop, GIMP, or Glimpse to view them.
\newpage
\section{Image file format}
If you open up the .ppm file in a text editor like Notepad,
you will see how the data is arranged:
\begin{lstlisting}[style=textfile]
P3
# Created by GIMP version 2.10.18 PNM plug-in
300 300
255
51
46
25
50
45
24
51
46
(and so on...)
\end{lstlisting}
\paragraph{Lines 1, 2, 3, and 4 are headers:}
\begin{itemize}
\item Line 1: Type of PPM file; should be P3.
\item Line 2: Comments from the exporting program.
\item Line 3: Width and Height of the image.
\item Line 4: Color depth of the file.
\end{itemize}
\paragraph{All the numbers after} are r, g, b values for each pixel...
\begin{lstlisting}[style=textfile]
51 pixel 1 red
46 pixel 1 green
25 pixel 1 blue
50 pixel 2 red
45 pixel 2 green
24 pixel 2 blue
(and so on...)
\end{lstlisting}
This is a very simple image file type with no compression,
but that makes it easy for us to work with in C++.
In our program, we will load in the images and save out modified
images, though we won't be able to view the images from within
our C++ program (we would need a special library to do that),
which is why you'll need an image editor on your computer.
\newpage
\section{Loading the image file}
Follow these steps to load in the image file:
\begin{enumerate}
\item Create an \texttt{ifstream} object named \texttt{input}. Open the \texttt{filename} for reading.
\item Check if opening the file failed and display an error message if it did.
~\\ \texttt{ if ( input.fail() ) { /* error */ } }
\item Create two buffer variables: a string and an int (like \texttt{strBuffer}, \texttt{intBuffer}).
\item Read the first two lines of the text file. You can store them in \texttt{strBuffer} since we don't need this data.
~\\ \texttt{ getline( input, strBuffer ); // Skip "P3" }
~\\ \texttt{ getline( input, strBuffer ); // Skip comment }
\item Skip the next two items, which are the width/height, using the \texttt{intBuffer}. These are hard coded in the program anyway.
~\\ \texttt{ input >> intBuffer; // Skip width }
~\\ \texttt{ input >> intBuffer; // Skip height }
\item Read in the next item into the \texttt{m\_colorDepth} variable.
~\\ \texttt{ input >> m\_colorDepth; }
\item Create two integer variables, \texttt{x} and \texttt{y}, and initialize them both to 0.
\item Create a while loop to read in three pixels at a time...
\begin{lstlisting}[style=code]
while ( input >> m_pixels[x][y].r
>> m_pixels[x][y].g
>> m_pixels[x][y].b )
{
}
\end{lstlisting}
\item Within this loop...
\begin{enumerate}
\item Increment \texttt{x} by 1.
\item If \texttt{x} is equal to \texttt{IMAGE\_WIDTH}, then increment \texttt{y} by 1, and reset \texttt{x} to 0.
\end{enumerate}
\end{enumerate}
That's all you need to load it. The while loop will continue looping until we run out of
text in the text file, and will stop on its own.
\newpage
\section{Saving the image file}
Saving the image will be similar, we just need to write out the same
data in the same order, making sure to include the headers before
writing out all the pixels. Do the following.
\begin{enumerate}
\item Create an \texttt{ofstream} object named \texttt{output}. Open the \texttt{filename} to write to.
\item Use the .fail() function to see if the opening the file failed - if so, output an error and return.
\item Output the header info:
\begin{enumerate}
\item \texttt{"P3"}
\item \texttt{"\# Comment"}
\item \texttt{IMAGE\_WIDTH} \texttt{IMAGE\_HEIGHT}
\item \texttt{m\_colorDepth}
\end{enumerate}
~\\