Primo commit di questa repo, è un bel progettino molto semplice da funzioni esplicative

This commit is contained in:
2026-03-15 20:05:01 +01:00
commit 4454225462
5 changed files with 284 additions and 0 deletions

8
.gitignore vendored Normal file
View File

@@ -0,0 +1,8 @@
# Ignoriamo le immagini
*.png
*.jpg
*.ppm
# Ingoriamo i gli oggetti
*.o
*.x

169
libImg.cpp Normal file
View 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;
}
}
}

40
libImg.h Normal file
View File

@@ -0,0 +1,40 @@
#include <vector>
#include <random>
#include <string>
#include <fstream>
#include <iostream>
#include <cassert>
#include <cmath>
#include <algorithm>
struct pixel {
unsigned char r, g, b;
bool operator==(const pixel& o) const { return r == o.r && g == o.g && b == o.b; }
bool operator!=(const pixel& o) const { return !(*this == o); }
bool operator>=(const pixel& o) const { return r - o.r + g - o.g + b - o.b > 0; }
float lum() const { return 0.2126f * r + 0.7152f * g + 0.0722f * b; }
float lumNorm() const { return lum() / 255.0f; }
};
using image = std::vector<std::vector<pixel>>;
//Variabili importanti
inline std::mt19937 rng(10);
inline std::uniform_int_distribution<unsigned int> dist(0, 255);
inline image errore(1, std::vector<pixel>(1, {0, 0, 0}));
bool save(const std::string& path, const image& matrix);
image load(const std::string& path, int& w, int& h);
bool images_equal(const image& a, const image& b);
unsigned long long countW(image &matrix);
image randomImage(int w, int h);
void BWimage(image &matrix, float lim);
void Grayimage(image &matrix);
float BWAimage(image &matrix);
void invertImage(image &matrix);
void gaussianImage(image &matrix, int dim);

50
main.cpp Normal file
View File

@@ -0,0 +1,50 @@
// magick malenia.jpg -define ppm:format=raw test.ppm
#include <bits/stdc++.h>
#include "libImg.h"
using namespace std;
const int WIDTH = 16 * 60;
const int HEIGHT = 9 * 60;
int main () {
/*
image matrix = randomImage(WIDTH, HEIGHT);
//BWimage(matrix, 0.70);
Grayimage(matrix);
if (!save("output.ppm", matrix, WIDTH, HEIGHT)) {
return -1;
}
int height, width;
image caricato = load("output.ppm", width, height);
if(images_equal(matrix, caricato)){
std::cout << "Cazzo funziona"<<endl;
}else {
std::cout << "MMMMMMMMM" <<endl;
}
std::cout << "Matrice: " << HEIGHT << "x" << WIDTH << "\n";
std::cout << "Caricato: " << height << "x" << width << "\n";
std::cout << "Pixel [0][0] matrice: "
<< (int)matrix[0][0].r << " " << (int)matrix[0][0].g << " " << (int)matrix[0][0].b << "\n";
std::cout << "Pixel [0][0] caricato: "
<< (int)caricato[0][0].r << " " << (int)caricato[0][0].g << " " << (int)caricato[0][0].b << "\n";
*/
int heightC, widthC;
image carica = load("test.ppm", widthC, heightC);
//Grayimage(carica);
//float numerone = BWAimage(carica);
//invertImage(carica);
if(!save("testOutput.ppm", carica)){
return -1;
}
//cout << "Numerone finale: " << numerone <<endl;
return 0;
}

17
makefile Normal file
View File

@@ -0,0 +1,17 @@
# Makefile incredibile per il progrettone
XX = g++
CXXFLAGS = -O2 -Wall -Wextra -Wpedantic -Wshadow -D_GLIBCXX_DEBUG -fsanitize=address -fsanitize=undefined -fno-sanitize-recover -Wshift-overflow=2
all: main.x
main.o: main.cpp
$(CXX) main.cpp -c $(CXXFLAGS)
libImg.o: libImg.cpp
$(CXX) libImg.cpp -c $(CXXFLAGS)
main.x: main.o libImg.o
$(CXX) main.o libImg.o -o main.x $(CXXFLAGS)
run: main.x
./main.x