Files
immagini/libImg.cpp

170 lines
3.5 KiB
C++

#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;
}
}
}