//*************************************//
//******** created by mamo139 *********//
//*** http://mamo139.altervista.org ***//
//*************************************//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
//*** strumenti gestione file bmp ***//
struct bmpfile {
long x;
long y;
char *** matrice;
};
char *** crea_bmp(char *nome, long x, long y);
struct bmpfile carica_bmp(char *nome);
void disegna_bmp(char *nome, char *** array, long x, long y);
//*** strumenti gestione colori ***//
struct rgb {
int red;
int green;
int blue;
};
struct rgb_d {
double red;
double green;
double blue;
};
struct hsv {
int hue;
int saturation;
int value;
};
struct hsv_d {
double hue;
double saturation;
double value;
};
struct rgb hsv_rgb(struct hsv hsv_map);
struct hsv rgb_hsv(struct rgb rgb_map);
//*** MAIN ***//
int main (void){
double peso1 = 0.65;
double peso2 = 0.65;
long x,y;
struct hsv hsv1;
struct hsv hsv2;
struct hsv hsvf;
struct rgb rgbf;
struct rgb rgb1;
struct rgb rgb2;
struct bmpfile img1 = carica_bmp("a.bmp");
struct bmpfile img2 = carica_bmp("b.bmp");
if(img1.x>img2.x) x = img2.x;
else x = img1.x;
if(img1.y>img2.y) y = img2.y;
else y = img1.y;
char *** mappanf = crea_bmp("out.bmp",x,y);
long i,j;
for(i=0;i<x;i++)
for(j=0;j<y;j++){
rgb1.red = (unsigned char) img1.matrice[i][j][2];
rgb1.green = (unsigned char) img1.matrice[i][j][1];
rgb1.blue = (unsigned char) img1.matrice[i][j][0];
rgb2.red = (unsigned char) img2.matrice[i][j][2];
rgb2.green = (unsigned char) img2.matrice[i][j][1];
rgb2.blue = (unsigned char) img2.matrice[i][j][0];
rgbf.red=(int)(rgb1.red*peso1+rgb2.red*peso2);
if(rgbf.red>255) rgbf.red = 255;
rgbf.green=(int)(rgb1.green*peso1+rgb2.green*peso2);
if(rgbf.green>255) rgbf.green = 255;
rgbf.blue=(int)(rgb1.blue*peso1+rgb2.blue*peso2);
if(rgbf.blue>255) rgbf.blue = 255;
mappanf[i][j][2]=rgbf.red;
mappanf[i][j][1]=rgbf.green;
mappanf[i][j][0]=rgbf.blue;
}
disegna_bmp("out.bmp",mappanf,x,y);
}
//****** FUNZIONI *******//
char *** crea_bmp(char *nome, long x, long y){
char buffer [55] = "\x42\x4d\x36\x39\xb1\x00\x00\x00\x00\x00" \
"\x36\x00\x00\x00\x28\x00\x00\x00\xe0\x08\x00\x00\xa8\x06" \
"\x00\x00\x01\x00\x18\x00\x00\x00\x00\x00\x00\x00\x00\x00" \
"\xc4\x0e\x00\x00\xc4\x0e\x00\x00\x00\x00\x00\x00\x00\x00" \
"\x00\x00";
buffer[18] = x%256;//asse x
buffer[19] = x/256;
buffer[22] = y%256;//asse y
buffer[23] = y/256;
FILE *stream;
stream = fopen(nome,"wb");
fwrite(buffer, 1, 54, stream);
fclose(stream);
char *** array;
int i, j, h;
array = (char***)malloc(x * sizeof(char *));
for(i=0; i<x; i++) {
array[i] = (char**)malloc(y * sizeof(char *));
for (j=0; j<y; j++)
array[i][j] = (char*)malloc(3 * sizeof(char *));
}
int i1,i2,i3;
for(i1=0; i1<x; i1++)
for (i2=0; i2<y; i2++)
for (i3=0; i3<3; i3++)
array[i1][i2][i3] = 0;
return array;
}
struct bmpfile carica_bmp(char *nome){
struct bmpfile dati;
long filesize,b,i,j,z=0;
char *** array;
char * buffer;
FILE * file;
file = fopen(nome,"rb");
fseek (file , 0 , SEEK_END);
filesize = ftell(file);
rewind(file);
buffer = (char *) malloc(filesize * sizeof(char *));
b = fread( buffer, 1, 54, file);
dati.x = ((unsigned char)buffer[18])+((unsigned char)buffer[19])*256;
dati.y = ((unsigned char)buffer[22])+((unsigned char)buffer[23])*256;
b = fread( buffer, 1, filesize, file);
array = (char***)malloc(dati.x * sizeof(char *));
for(i=0; i<dati.x; i++) {
array[i] = (char**)malloc(dati.y * sizeof(char *));
for (j=0; j<dati.y; j++)
array[i][j] = (char*)malloc(3 * sizeof(char *));
}
for(i=0; i<dati.x; i++)
for (j=0; j<dati.y; j++){
array[i][j][0]=buffer[z];
array[i][j][1]=buffer[z+1];
array[i][j][2]=buffer[z+2];
z=z+3;
}
dati.matrice = array;
return dati;
}
void disegna_bmp(char *nome, char *** array, long x, long y){
FILE *stream;
stream = fopen(nome,"ab");
int i1,i2;
for(i1=0; i1<x; i1++)
for (i2=0; i2<y; i2++)
fwrite(array[i1][i2], 1, 3, stream);
fclose(stream);
}
struct rgb hsv_rgb(struct hsv hsv_map){
struct rgb_d rgb_map;
struct rgb rgb_int;
double H = ((double)hsv_map.hue);
double S = ((double)hsv_map.saturation)/255;
double V = ((double)hsv_map.value)/255;
double hi = ((int)(H/60))%6;
double f = (H/60) - (double)hi;
double p = V*(1-S);
double q = V*(1-(f*S));
double t = V*(1-(1-f)*S);
if (hi == 0){ rgb_map.red=V; rgb_map.green=t; rgb_map.blue=p;}
else if (hi == 1){ rgb_map.red=q*255; rgb_map.green=V; rgb_map.blue=p;}
else if (hi == 2){ rgb_map.red=p*255; rgb_map.green=V; rgb_map.blue=t;}
else if (hi == 3){ rgb_map.red=p*255; rgb_map.green=q; rgb_map.blue=V;}
else if (hi == 4){ rgb_map.red=t*255; rgb_map.green=p; rgb_map.blue=V;}
else if (hi == 5){ rgb_map.red=V*255; rgb_map.green=p; rgb_map.blue=q;}
rgb_int.red = (int)(rgb_map.red*255);
rgb_int.green = (int)(rgb_map.green*255);
rgb_int.blue = (int)(rgb_map.blue*255);
return rgb_int;
}
struct hsv rgb_hsv(struct rgb rgb_map){
struct rgb_d rgb_d;
struct hsv_d hsv_d;
struct hsv hsv;
//(0,1)
rgb_d.red= ((double)rgb_map.red)/255;
rgb_d.green= ((double)rgb_map.green)/255;
rgb_d.blue= ((double)rgb_map.blue)/255;
double gradi = 0;
double MAX= 0, MIN=0, numeratore=0;
double H = 0; //tonalità
if( rgb_d.red == rgb_d.green && rgb_d.green == rgb_d.blue) { H=0; MAX = rgb_d.red; MIN = rgb_d.red; } //tonalità trovata *********
else{
if( rgb_d.red >= rgb_d.green && rgb_d.red >= rgb_d.blue && rgb_d.green >= rgb_d.blue){ //rosso maggiore blu minore
MAX = rgb_d.red;
MIN = rgb_d.blue;
gradi = 0;
numeratore = rgb_d.green-rgb_d.blue;
}
else if( rgb_d.red >= rgb_d.green && rgb_d.red >= rgb_d.blue && rgb_d.green < rgb_d.blue){ //rosso maggiore verde minore
MAX = rgb_d.red;
MIN = rgb_d.green;
gradi = 360;
numeratore = rgb_d.green-rgb_d.blue;
}
else if( rgb_d.green >= rgb_d.red && rgb_d.green >= rgb_d.blue && rgb_d.red <= rgb_d.blue){ //verde maggiore, rosso minore
MAX = rgb_d.green;
MIN = rgb_d.red;
gradi = 120;
numeratore = rgb_d.blue-rgb_d.red;
}
else if( rgb_d.green >= rgb_d.red && rgb_d.green >= rgb_d.blue && rgb_d.blue < rgb_d.red){ //verde maggiore, blu minore
MAX = rgb_d.green;
MIN = rgb_d.blue;
gradi = 120;
numeratore = rgb_d.blue-rgb_d.red;
}
else if( rgb_d.blue >= rgb_d.red && rgb_d.blue >= rgb_d.green && rgb_d.red <= rgb_d.green){ //blu maggiore, rosso minore
MAX = rgb_d.blue;
MIN = rgb_d.red;
gradi = 240;
numeratore = rgb_d.red-rgb_d.green;
}
else if( rgb_d.blue >= rgb_d.red && rgb_d.blue >= rgb_d.green && rgb_d.green < rgb_d.red){ //blu maggiore, verde minore
MAX = rgb_d.blue;
MIN = rgb_d.green;
gradi = 240;
numeratore = rgb_d.red-rgb_d.green;
}
H = ( (int) (60*(numeratore/(MAX-MIN)) + gradi) ) % 360;//tonalità trovata ***********
}
double S = 0;//saturazione
if(MAX == 0) S = 0; //saturazione trovata **********
else S = (MAX - MIN) / MAX; //saturazione trovata **********
double V = MAX; //luminosità/valore trovata **********
hsv_d.hue=H;
hsv_d.saturation=S;
hsv_d.value=V;
hsv.hue= (int)(hsv_d.hue);
hsv.saturation= (int)(hsv_d.saturation * 255);
hsv.value= (int)(hsv_d.value * 255);
return hsv;
}