Primo commit di questa repo, è un bel progettino molto semplice da funzioni esplicative
This commit is contained in:
169
libImg.cpp
Normal file
169
libImg.cpp
Normal file
@@ -0,0 +1,169 @@
|
||||
#include "libImg.h"
|
||||
|
||||
#define ASSERT_MSG(cond, msg) \
|
||||
do { if (!(cond)) { std::cerr << msg << std::endl; assert(cond); } } while (0)
|
||||
|
||||
// Salva un immagine in formato ppm P6 255
|
||||
bool save(const std::string& path, const image& matrix){
|
||||
std::ofstream f(path, std::ios::binary);
|
||||
if(!f){
|
||||
std::cerr<<"Errore in save"<<std::endl;
|
||||
return false;
|
||||
}
|
||||
int w = matrix[0].size();
|
||||
int h = matrix.size();
|
||||
f << "P6\n" << w << " " << h <<"\n255\n";
|
||||
|
||||
for (int y = 0; y < h; y++) {
|
||||
for(int x = 0; x < w; x++){
|
||||
f.write(reinterpret_cast<const char*>(&matrix[y][x]), 3);
|
||||
}
|
||||
}
|
||||
|
||||
f.close();
|
||||
std::cout << "Fine salvato"<<std::endl;
|
||||
return true;
|
||||
}
|
||||
|
||||
//Carica un immagine in formato ppm P6 255
|
||||
image load(const std::string& path, int& w, int& h){
|
||||
std::ifstream f(path, std::ios::binary);
|
||||
if (!f) {
|
||||
std::cerr << "File non aperto" <<std::endl;
|
||||
w = 1;
|
||||
h = 1;
|
||||
return errore;
|
||||
}
|
||||
std::string magic;
|
||||
int val;
|
||||
f >> magic >> w >> h >> val;
|
||||
if(magic != "P6"){
|
||||
std::cerr << " Magic Sbagliato"<<std::endl;
|
||||
w = 1;
|
||||
h = 1;
|
||||
return errore;
|
||||
}
|
||||
if(val != 255){
|
||||
std::cerr << "Dimensione sbagliata dei colori "<<val<<std::endl;
|
||||
w = 1;
|
||||
h = 1;
|
||||
return errore;
|
||||
}
|
||||
|
||||
char sep;
|
||||
f.get(sep);
|
||||
|
||||
image matrix(h, std::vector<pixel>(w));
|
||||
for(int y = 0; y < h; y++){
|
||||
for(int x = 0; x < w; x++){
|
||||
f.read(reinterpret_cast<char*>(&matrix[y][x]), 3);
|
||||
if(f.gcount() != 3){
|
||||
std::cerr << "Distanza sbagliata" <<std::endl;
|
||||
w = 1;
|
||||
h = 1;
|
||||
std::cerr << "Strano, mancano i pixel"<<std::endl;
|
||||
return errore;
|
||||
}
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
//Controlla l'ugualianza di 2 immagini
|
||||
// usa tutte le tecniche che sono standard + comparatore tra pixel
|
||||
bool images_equal(const image& a, const image& b) {
|
||||
if (a.size() != b.size() || a[0].size() != b[0].size()) return false;
|
||||
return a == b;
|
||||
}
|
||||
|
||||
//Genera rumore pseudo-casuale
|
||||
image randomImage(int w, int h){
|
||||
image matrix(h, std::vector<pixel>(w));
|
||||
|
||||
for(int y = 0; y < h; ++y){
|
||||
for(int x = 0; x < w; ++x){
|
||||
matrix[y][x] = {
|
||||
static_cast<unsigned char>(dist(rng)),
|
||||
static_cast<unsigned char>(dist(rng)),
|
||||
static_cast<unsigned char>(dist(rng))
|
||||
};
|
||||
}
|
||||
}
|
||||
return matrix;
|
||||
}
|
||||
|
||||
//converte un immagini in bianco e nero
|
||||
void BWimage(image &matrix, float lim){
|
||||
ASSERT_MSG(lim >= 0 && lim <= 1, "Il valore limite deve essere tra 0-1");
|
||||
|
||||
const pixel t = {
|
||||
static_cast<unsigned char>(lim*255),
|
||||
static_cast<unsigned char>(lim*255),
|
||||
static_cast<unsigned char>(lim*255)
|
||||
};
|
||||
|
||||
for(auto &i: matrix){
|
||||
for(auto &p: i){
|
||||
if(p >= t)
|
||||
p = {255,255,255};
|
||||
else
|
||||
p = {0, 0, 0};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//converte un immagine in scala di grigi
|
||||
void Grayimage(image &matrix){
|
||||
for(auto &i: matrix){
|
||||
for(auto &p: i){
|
||||
short s = (short) p.lum();
|
||||
p = {
|
||||
static_cast<unsigned char>(s),
|
||||
static_cast<unsigned char>(s),
|
||||
static_cast<unsigned char>(s)
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
unsigned long long countW(image &matrix){
|
||||
int ans = 0;
|
||||
pixel max = {255, 255, 255};
|
||||
for(const auto &y:matrix){
|
||||
for(const auto &p: y){
|
||||
if(p == max)ans++;
|
||||
}
|
||||
}
|
||||
return ans;
|
||||
}
|
||||
// +- 0,25 0,125 ...
|
||||
float BWAimage(image &matrix){
|
||||
image test;
|
||||
float lim = 0.5f;
|
||||
unsigned long long avg = matrix.size() * matrix[0].size() / 2;
|
||||
for(int i = 4; i <= 1<<6; i = i<<1){
|
||||
test = matrix;
|
||||
BWimage(test, lim);
|
||||
if(countW(test) < avg){
|
||||
lim -= 1.0f/i;
|
||||
}
|
||||
else{
|
||||
lim += 1.0f/i;
|
||||
}
|
||||
// Ez debug
|
||||
// std::cout<<"Il lim è: "<<lim<<std::endl;
|
||||
}
|
||||
matrix = test;
|
||||
return lim;
|
||||
}
|
||||
|
||||
void invertImage(image &matrix){
|
||||
for(auto &y:matrix){
|
||||
for(auto &p:y){
|
||||
p.r ^= 0xFF;
|
||||
p.g ^= 0xFF;
|
||||
p.b ^= 0xFF;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user