-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Created image class to transform images- Routines included 1. Spotlig…
…ht, 2. Greyscale, 3. Illuminate and 4. Watermark
- Loading branch information
0 parents
commit 22b95db
Showing
18 changed files
with
22,330 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
/** | ||
* @file HSLAPixel.cpp | ||
*/ | ||
|
||
#include <cmath> | ||
#include <iostream> | ||
#include "HSLAPixel.h" | ||
using namespace std; | ||
|
||
namespace Image { | ||
|
||
int HSLAPixel::cdistance(double x, double y){ | ||
|
||
int rvalue = (int(x) - int(y) + 180) % 360 - 180; | ||
|
||
return rvalue; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
/** | ||
* @file HSLAPixel.h | ||
* | ||
* @author University of Illinois CS 225 Course Staff | ||
* @version 2018r1-lab1 - Updated for CS 400 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <iostream> | ||
#include <sstream> | ||
|
||
namespace Image { | ||
|
||
class HSLAPixel{ | ||
|
||
public: | ||
int cdistance(double x, double y); | ||
double h; | ||
double s; | ||
double l; | ||
double a; | ||
}; | ||
|
||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,214 @@ | ||
/** | ||
* @file PNG.cpp | ||
* Implementation of a simple PNG class using HSLAPixels and the lodepng PNG library. | ||
* | ||
* @author University of Illinois CS 225 Course Staff | ||
* @version 2018r1-lab1 - Updated for CS 400 | ||
*/ | ||
|
||
#include <iostream> | ||
#include <string> | ||
#include <algorithm> | ||
#include <functional> | ||
#include <cassert> | ||
#include "lodepng/lodepng.h" | ||
#include "HSLAPixel.h" | ||
#include "PNG.h" | ||
#include "RGB_HSL.h" | ||
|
||
namespace Image { | ||
void PNG::_copy(PNG const & other) { | ||
// Clear self | ||
delete[] imageData_; | ||
|
||
// Copy `other` to self | ||
width_ = other.width_; | ||
height_ = other.height_; | ||
imageData_ = new HSLAPixel[width_ * height_]; | ||
for (unsigned i = 0; i < width_ * height_; i++) { | ||
imageData_[i] = other.imageData_[i]; | ||
} | ||
} | ||
|
||
PNG::PNG() { | ||
width_ = 0; | ||
height_ = 0; | ||
imageData_ = NULL; | ||
} | ||
|
||
PNG::PNG(unsigned int width, unsigned int height) { | ||
width_ = width; | ||
height_ = height; | ||
imageData_ = new HSLAPixel[width * height]; | ||
} | ||
|
||
PNG::PNG(PNG const & other) { | ||
imageData_ = NULL; | ||
_copy(other); | ||
} | ||
|
||
PNG::~PNG() { | ||
delete[] imageData_; | ||
} | ||
|
||
PNG const & PNG::operator=(PNG const & other) { | ||
if (this != &other) { _copy(other); } | ||
return *this; | ||
} | ||
|
||
bool PNG::operator==(PNG const & other) const { | ||
if (width_ != other.width_) { return false; } | ||
if (height_ != other.height_) { return false; } | ||
|
||
for (unsigned i = 0; i < width_ * height_; i++) { | ||
HSLAPixel & p1 = imageData_[i]; | ||
HSLAPixel & p2 = other.imageData_[i]; | ||
if (p1.h != p2.h || p1.s != p2.s || p1.l != p2.l || p1.a != p2.a) { return false; } | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool PNG::operator!=(PNG const & other) const { | ||
return !(*this == other); | ||
} | ||
|
||
HSLAPixel & PNG::getPixel(unsigned int x, unsigned int y) const { | ||
if (width_ == 0 || height_ == 0) { | ||
cerr << "ERROR: Call to uiuc::PNG::getPixel() made on an image with no pixels." << endl; | ||
assert(width_ > 0); | ||
assert(height_ > 0); | ||
} | ||
|
||
if (x >= width_) { | ||
cerr << "WARNING: Call to uiuc::PNG::getPixel(" << x << "," << y << ") tries to access x=" << x | ||
<< ", which is outside of the image (image width: " << width_ << ")." << endl; | ||
cerr << " : Truncating x to " << (width_ - 1) << endl; | ||
x = width_ - 1; | ||
} | ||
|
||
if (y >= height_) { | ||
cerr << "WARNING: Call to uiuc::PNG::getPixel(" << x << "," << y << ") tries to access y=" << y | ||
<< ", which is outside of the image (image height: " << height_ << ")." << endl; | ||
cerr << " : Truncating y to " << (height_ - 1) << endl; | ||
y = height_ - 1; | ||
} | ||
|
||
unsigned index = x + (y * width_); | ||
return imageData_[index]; | ||
} | ||
|
||
bool PNG::readFromFile(string const & fileName) { | ||
vector<unsigned char> byteData; | ||
unsigned error = lodepng::decode(byteData, width_, height_, fileName); | ||
|
||
if (error) { | ||
cerr << "PNG decoder error " << error << ": " << lodepng_error_text(error) << endl; | ||
return false; | ||
} | ||
|
||
delete[] imageData_; | ||
imageData_ = new HSLAPixel[width_ * height_]; | ||
|
||
for (unsigned i = 0; i < byteData.size(); i += 4) { | ||
rgbaColor rgb; | ||
rgb.r = byteData[i]; | ||
rgb.g = byteData[i + 1]; | ||
rgb.b = byteData[i + 2]; | ||
rgb.a = byteData[i + 3]; | ||
|
||
hslaColor hsl = rgb2hsl(rgb); | ||
HSLAPixel & pixel = imageData_[i/4]; | ||
pixel.h = hsl.h; | ||
pixel.s = hsl.s; | ||
pixel.l = hsl.l; | ||
pixel.a = hsl.a; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
bool PNG::writeToFile(string const & fileName) { | ||
unsigned char *byteData = new unsigned char[width_ * height_ * 4]; | ||
|
||
for (unsigned i = 0; i < width_ * height_; i++) { | ||
hslaColor hsl; | ||
hsl.h = imageData_[i].h; | ||
hsl.s = imageData_[i].s; | ||
hsl.l = imageData_[i].l; | ||
hsl.a = imageData_[i].a; | ||
|
||
rgbaColor rgb = hsl2rgb(hsl); | ||
|
||
byteData[(i * 4)] = rgb.r; | ||
byteData[(i * 4) + 1] = rgb.g; | ||
byteData[(i * 4) + 2] = rgb.b; | ||
byteData[(i * 4) + 3] = rgb.a; | ||
} | ||
|
||
unsigned error = lodepng::encode(fileName, byteData, width_, height_); | ||
if (error) { | ||
cerr << "PNG encoding error " << error << ": " << lodepng_error_text(error) << endl; | ||
} | ||
|
||
delete[] byteData; | ||
return (error == 0); | ||
} | ||
|
||
unsigned int PNG::width() const { | ||
return width_; | ||
} | ||
|
||
unsigned int PNG::height() const { | ||
return height_; | ||
} | ||
|
||
void PNG::resize(unsigned int newWidth, unsigned int newHeight) { | ||
// Create a new vector to store the image data for the new (resized) image | ||
HSLAPixel * newImageData = new HSLAPixel[newWidth * newHeight]; | ||
|
||
// Copy the current data to the new image data, using the existing pixel | ||
// for coordinates within the bounds of the old image size | ||
for (unsigned x = 0; x < newWidth; x++) { | ||
for (unsigned y = 0; y < newHeight; y++) { | ||
if (x < width_ && y < height_) { | ||
HSLAPixel & oldPixel = this->getPixel(x, y); | ||
HSLAPixel & newPixel = newImageData[ (x + (y * newWidth)) ]; | ||
newPixel = oldPixel; | ||
} | ||
} | ||
} | ||
|
||
// Clear the existing image | ||
delete[] imageData_; | ||
|
||
// Update the image to reflect the new image size and data | ||
width_ = newWidth; | ||
height_ = newHeight; | ||
imageData_ = newImageData; | ||
} | ||
|
||
std::size_t PNG::computeHash() const { | ||
std::hash<float> hashFunction; | ||
std::size_t hash = 0; | ||
|
||
|
||
for (unsigned x = 0; x < this->width(); x++) { | ||
for (unsigned y = 0; y < this->height(); y++) { | ||
HSLAPixel & pixel = this->getPixel(x, y); | ||
hash = (hash << 1) + hash + hashFunction(pixel.h); | ||
hash = (hash << 1) + hash + hashFunction(pixel.s); | ||
hash = (hash << 1) + hash + hashFunction(pixel.l); | ||
hash = (hash << 1) + hash + hashFunction(pixel.a); | ||
} | ||
} | ||
|
||
return hash; | ||
} | ||
|
||
std::ostream & operator << ( std::ostream& os, PNG const& png ) { | ||
os << "PNG(w=" << png.width() << ", h=" << png.height() << ", hash=" << std::hex << png.computeHash() << std::dec << ")"; | ||
return os; | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,131 @@ | ||
/** | ||
* @file PNG.h | ||
* | ||
* @author University of Illinois CS 225 Course Staff | ||
* @version 2018r1 - Updated for CS 400 | ||
*/ | ||
|
||
#pragma once | ||
|
||
#include <string> | ||
#include <vector> | ||
#include "HSLAPixel.h" | ||
|
||
using namespace std; | ||
|
||
namespace Image { | ||
class PNG { | ||
public: | ||
/** | ||
* Creates an empty PNG image. | ||
*/ | ||
PNG(); | ||
|
||
/** | ||
* Creates a PNG image of the specified dimensions. | ||
* @param width Width of the new image. | ||
* @param height Height of the new image. | ||
*/ | ||
PNG(unsigned int width, unsigned int height); | ||
|
||
/** | ||
* Copy constructor: creates a new PNG image that is a copy of | ||
* another. | ||
* @param other PNG to be copied. | ||
*/ | ||
PNG(PNG const & other); | ||
|
||
/** | ||
* Destructor: frees all memory associated with a given PNG object. | ||
* Invoked by the system. | ||
*/ | ||
~PNG(); | ||
|
||
/** | ||
* Assignment operator for setting two PNGs equal to one another. | ||
* @param other Image to copy into the current image. | ||
* @return The current image for assignment chaining. | ||
*/ | ||
PNG const & operator= (PNG const & other); | ||
|
||
/** | ||
* Equality operator: checks if two images are the same. | ||
* @param other Image to be checked. | ||
* @return Whether the current image is equal to the other image. | ||
*/ | ||
bool operator== (PNG const & other) const; | ||
|
||
/** | ||
* Inequality operator: checks if two images are different. | ||
* @param other Image to be checked. | ||
* @return Whether the current image differs from the other image. | ||
*/ | ||
bool operator!= (PNG const & other) const; | ||
|
||
|
||
/** | ||
* Reads in a PNG image from a file. | ||
* Overwrites any current image content in the PNG. | ||
* @param fileName Name of the file to be read from. | ||
* @return true, if the image was successfully read and loaded. | ||
*/ | ||
bool readFromFile(string const & fileName); | ||
|
||
/** | ||
* Writes a PNG image to a file. | ||
* @param fileName Name of the file to be written. | ||
* @return true, if the image was successfully written. | ||
*/ | ||
bool writeToFile(string const & fileName); | ||
|
||
/** | ||
* Pixel access operator. Gets a reference to the pixel at the given | ||
* coordinates in the image. (0,0) is the upper left corner. | ||
* This reference allows the image to be changed. | ||
* @param x X-coordinate for the pixel reference to be grabbed from. | ||
* @param y Y-coordinate for the pixel reference to be grabbed from. | ||
* @return A reference to the pixel at the given coordinates. | ||
*/ | ||
HSLAPixel & getPixel(unsigned int x, unsigned int y) const; | ||
|
||
/** | ||
* Gets the width of this image. | ||
* @return Width of the image. | ||
*/ | ||
unsigned int width() const; | ||
|
||
/** | ||
* Gets the height of this image. | ||
* @return Height of the image. | ||
*/ | ||
unsigned int height() const; | ||
|
||
/** | ||
* Resizes the image to the given coordinates. Attempts to preserve | ||
* existing pixel data in the image when doing so, but will crop if | ||
* necessary. No pixel interpolation is done. | ||
* @param newWidth New width of the image. | ||
* @param newHeight New height of the image. | ||
*/ | ||
void resize(unsigned int newWidth, unsigned int newHeight); | ||
|
||
/** | ||
* Computes a hash of the contents of the image. | ||
*/ | ||
std::size_t computeHash() const; | ||
|
||
private: | ||
unsigned int width_; /*< Width of the image */ | ||
unsigned int height_; /*< Height of the image */ | ||
HSLAPixel *imageData_; /*< Array of pixels */ | ||
HSLAPixel defaultPixel_; /*< Default pixel, returned in cases of errors */ | ||
|
||
/** | ||
* Copeies the contents of `other` to self | ||
*/ | ||
void _copy(PNG const & other); | ||
}; | ||
|
||
std::ostream & operator<<(std::ostream & out, PNG const & pixel); | ||
std::stringstream & operator<<(std::stringstream & out, PNG const & pixel); | ||
} |
Oops, something went wrong.