Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- //╔═══════════════════════════════════════════╗\\
- //║ Alex Braniff - CpSc246 Adv Programming ║\\
- //║ Spring 2013 - Pixelating PPM Files ║\\
- //╚═══════════════════════════════════════════╝\\
- #include <iostream>
- #include <string>
- #include <fstream>
- #include <iomanip>
- using namespace std;
- //My bag to hold pixel information
- struct Pixel{
- int red, green, blue;
- };
- //╔═══════════════════════════════════════════╗\\
- //║ Global Variable Library ║\\
- //╚═══════════════════════════════════════════╝\\
- const int MAXCOLS = 882;
- const int MAXROWS = 883;
- const int PSEUDOMAXROWS = 50;
- //╔═══════════════════════════════════════════╗\\
- //║ Function Prototypes ║\\
- //╚═══════════════════════════════════════════╝\\
- void initialize( bool& FLAG,
- int& squareSize,
- string& inFileName,
- string& outFileName,
- ifstream& inFile,
- ofstream& outFile,
- int& numRows,
- int& numCols,
- int& maxColor
- );
- void readPixelStripe( Pixel pixArray[][MAXCOLS],
- int stripe,
- int squareSize,
- ifstream& inFile
- );
- void readPixel( Pixel pixArray[][MAXCOLS],
- int stripe,
- int row,
- int col,
- ifstream& inFile
- );
- void getAveragesForRGB( Pixel pixArray[][MAXCOLS],
- int squareSize,
- int square,
- int numSquaresPerStripe
- );
- void writePixel( int redAvg,
- int greenAvg,
- int blueAvg,
- ofstream& outFile
- );
- void getUserPreferences( bool& FLAG,
- int& squareSize,
- string& inFileName,
- string& outFileName,
- ifstream& inFile,
- ofstream& outFile
- );
- void printHeading();
- //╔═══════════════════════════════════════════╗\\
- //║ Main ║\\
- //╚═══════════════════════════════════════════╝\\
- int main(){
- //═════════════Variable Dictionary═════════════\\
- Pixel pixArray[PSEUDOMAXROWS][MAXCOLS]; //store pixel info for a stripe
- int numRows, numCols, maxColor; //ppm file attributes
- int squareSize; //store how big each square should be
- bool FLAG = 0; //generic FLAG variable
- string inFileName; //hold path to inFile from user input
- string outFileName; //hold path to outFile from user input
- ifstream inFile; //input file
- ofstream outFile; //output file
- //go through initialization of key components of program
- initialize(FLAG, squareSize, inFileName, outFileName, inFile, outFile, numRows, numCols, maxColor);
- cout << "\n\nProcessing image\n\n";
- //set some variables up with useful info
- int numStripes = MAXCOLS / squareSize; //number of stripes in image
- int numSquaresPerStripe = MAXROWS / squareSize; //number of squares in each stripe
- //initialize averages for future use
- int redAvg, greenAvg, blueAvg;
- for(int stripe=0;stripe<=numStripes;stripe++){//go through each stripe
- cout << "\r" << stripe << " out of " << numStripes;//let user know we're working
- readPixelStripe(pixArray, stripe, squareSize, inFile);//read in one stripe
- for(int square=0;square<numSquaresPerStripe;square++){//go through each square in each stripe
- getAveragesForRGB(pixArray, squareSize, square, numSquaresPerStripe);//find the average RGB value for the current square and replace array data
- }
- for(int row=0;row<squareSize;row++){
- for(int col=0;col<MAXCOLS;col++){//write each average in the stripe to the outFile
- writePixel(pixArray[row][col].red, pixArray[row][col].green, pixArray[row][col].blue, outFile);
- }
- }
- }
- inFile.close(); //must close files
- outFile.close();
- //need this to denote a good termination
- cout<<"\n\n\n\t\tNormal Termination ***\n";
- //allow user to see stuff on the screen
- system("PAUSE");
- return 0;
- }//end of main
- //C:\Development\C++\CPSC246\Braniff.ppm
- //C:\Development\C++\CPSC246\ffinarB.ppm
- //══════════════════Initialize══════════════════\\
- void initialize(bool& FLAG, int& squareSize, string& inFileName, string& outFileName, ifstream& inFile, ofstream& outFile, int& numRows, int& numCols, int& maxColor){
- //This routine will setup our files and process PPM header
- string str; //string to hold header info
- //set the attributes to zero: then if any of the
- // file i/o goes bad, the caller will have zero data
- numRows = numCols = maxColor = 0;
- printHeading(); //handles mandatory CpSc246 Headers
- getUserPreferences(FLAG, squareSize, inFileName, outFileName, inFile, outFile);//gets input output files
- //both files opened, so process (and verify) the header info
- getline(inFile,str); //must start with "P3"
- if (!(str.compare("P3") == 0)) {//error
- cerr<<"Bad file header: not P3\n";
- inFile.close();
- outFile.close();
- return;
- } //okay
- else //we're okay - so write header to new file
- outFile<<str<<endl;
- //get the comment line
- getline(inFile,str); //get comment
- if (str.at(0) != '#'){//error
- cerr<<"Missing comment in line 2\n";
- inFile.close();
- outFile.close();
- return;
- }
- else //okay
- outFile<<str<<endl; //write it out to new file
- //get file attributes & put to new file, too.
- inFile >> numCols >> numRows >> maxColor;
- outFile << numCols << ' ' << numRows << endl
- << maxColor << endl;
- }//initialize
- //get user input for file paths and squareSize
- void getUserPreferences(bool& FLAG, int& squareSize, string& inFileName, string& outFileName, ifstream& inFile, ofstream& outFile){
- while(FLAG == 0){//Get input file path
- cout << "\nPath of file to be pixelated: ";
- cin >> inFileName;//placeholder for file path
- inFile.open(inFileName.c_str());//open file using the string inputted
- if(inFile.is_open()){//make sure input file exists
- FLAG = 1;//get out of loop
- }else{//reset loop
- inFileName = "";
- inFile.close();
- cout << "\nFile does not exist.\n";
- }
- }
- //reset flag variable for use again
- FLAG = 0;
- int areYouSure = 0;//make sure user wants to use this file
- while(FLAG == 0){//get output file path
- cout << "\nPath of file to be written: ";
- cin >> outFileName;//placeholder for file path
- outFile.open(outFileName.c_str());//open file using the string inputted
- if(outFile.is_open()){//make sure output file path exists
- cout << "\nAre you sure?\n0 - NO\n1 - YES\n\n";
- cin >> areYouSure;
- if(areYouSure != 1){//reset loop if not sure
- areYouSure = 0;
- outFileName = "";
- outFile.close();
- }else{//get out of loop
- FLAG = 1;
- }
- }else{//get out of loop
- FLAG = 1;
- }
- }
- //reset flag variable for use again
- FLAG = 0;
- while(FLAG == 0){//get size of squares to be pixelated
- cout << "\nHow big do you want the pixelated squares to be? (15-50)\n";
- cin >> squareSize;
- if(squareSize <= 50 && squareSize >=15){//make sure nuber is between 15 and 50
- FLAG = 1;//get out of loop
- }else{//reset loop for reiteration
- squareSize = 0;
- cout << "\nThe value must be between 15 and 50.\n";
- }
- }
- }
- //═══════════════════Heading════════════════════\\
- //outputs headin information required for course
- void printHeading(){
- cout << "+============================================+\n";
- cout << "+===Alex Braniff===CpSc246 Adv Programming===+\n";
- cout << "+===Spring 2013=======Pixelating PPM Files===+\n";
- cout << "+============================================+\n";
- }
- //══════════════════Read Stripe═══════════════════\\
- //read in one stripe of pixels to pixArray[][]
- void readPixelStripe(Pixel pixArray[][MAXCOLS], int stripe, int squareSize, ifstream& inFile){
- for(int row=0;row<squareSize;row++){
- for(int col=0;col<MAXCOLS;col++){
- readPixel(pixArray, stripe, row, col, inFile);
- }
- }
- }
- //══════════════════Averages═══════════════════\\
- void getAveragesForRGB(Pixel pixArray[][MAXCOLS], int squareSize, int square, int numSquaresPerStripe){
- //initialize variables needed for function
- int start, stop;
- int redAvg, greenAvg, blueAvg;
- //reset averages for current square's usage
- redAvg = 0;
- greenAvg = 0;
- blueAvg = 0;
- start = 0;//reset start number
- for(int row=0;row<squareSize;row++){
- if(row != 0)//adds one to the start as long as it doesn't NEED to be 0
- start = ((square * MAXROWS) / (MAXCOLS / squareSize)) + 1;//starting point for loop over the columns
- stop = (((square + 1) * MAXROWS) / (MAXCOLS / squareSize));//stopping point for ^^^
- for(int col=start;col<stop;col++){
- //add each rgb value to the sum to be divided later
- redAvg += pixArray[row][col].red;
- greenAvg += pixArray[row][col].green;
- blueAvg += pixArray[row][col].blue;
- }
- }
- //divide by number of pixels in square for average
- redAvg /= (squareSize * squareSize);
- greenAvg /= (squareSize * squareSize);
- blueAvg /= (squareSize * squareSize);
- start = 0;//reset start number
- for(int row=0;row<squareSize;row++){
- if(row != 0)
- start = ((square * MAXROWS) / (MAXCOLS / squareSize)) + 1;
- stop = (((square + 1) * MAXROWS) / (MAXCOLS / squareSize));
- for(int col=start;col<stop;col++){
- //write each average into each piece of the array
- pixArray[row][col].red = redAvg;
- pixArray[row][col].green = greenAvg;
- pixArray[row][col].blue = blueAvg;
- }
- }
- }
- //══════════════════Read Pixel═══════════════════\\
- //reads pixel information from the inFile
- void readPixel(Pixel pixArray[][MAXCOLS], int stripe, int row, int col, ifstream& inFile){
- inFile>>pixArray[row][col].red>>pixArray[row][col].green>>pixArray[row][col].blue;
- string stringReturn = to_string(pixArray[row][col].red) + "-" + to_string(pixArray[row][col].green) + "-" + to_string(pixArray[row][col].blue);
- }
- //══════════════════Write Pixel══════════════════\\
- //takes three integers and writes them to the outFile as pixel info
- void writePixel(int redAvg, int greenAvg, int blueAvg, ofstream& outFile){
- outFile << redAvg << ' ' //write 3 values (RGB) per line
- << greenAvg << ' '
- << blueAvg << endl;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement