Skip to content

Instantly share code, notes, and snippets.

@ciembor
Created December 19, 2011 14:45
Show Gist options
  • Select an option

  • Save ciembor/1497512 to your computer and use it in GitHub Desktop.

Select an option

Save ciembor/1497512 to your computer and use it in GitHub Desktop.
Brightness normalization
/*
* author: Maciej Ciemborowicz
* Jagiellonian University
* ZGK 2011/2012
*
* gcc gd_wewy.o bn.c -o bn -lgd -ansi -Wall -pedantic
*/
#include <stdio.h>
#include <math.h>
#include <gd.h>
#include "gd_wewy.h"
#define MIN(a,b) ((a)<(b)?(a):(b))
#define MAX(a,b) ((a)>(b)?(a):(b))
typedef struct rgb {
float r, g, b;
} RGB;
typedef struct hsv {
float h, s, v;
} HSV;
/* based on: http://www.algorytm.org/modele-barw/transformacja-hsv-rgb/hsv-rgb-c.html */
RGB hsv2rgb(float hue, float sat, float val) {
float red, grn, blu;
float i, f, p, q, t;
RGB result;
if(val==0) {
red = 0;
grn = 0;
blu = 0;
}
else {
hue/=60;
i = floor(hue);
f = hue-i;
p = val*(1-sat);
q = val*(1-(sat*f));
t = val*(1-(sat*(1-f)));
if (i==0) {red=val; grn=t; blu=p;}
else if (i==1) {red=q; grn=val; blu=p;}
else if (i==2) {red=p; grn=val; blu=t;}
else if (i==3) {red=p; grn=q; blu=val;}
else if (i==4) {red=t; grn=p; blu=val;}
else if (i==5) {red=val; grn=p; blu=q;}
}
result.r = red;
result.g = grn;
result.b = blu;
return result;
}
/* based on: http://www.algorytm.org/modele-barw/transformacja-hsv-rgb/hsv-rgb-c.html */
HSV rgb2hsv(float red, float grn, float blu){
float hue, sat, val;
float x, f, i;
HSV result;
x = MIN(MIN(red, grn), blu);
val = MAX(MAX(red, grn), blu);
if (x == val){
hue = 0;
sat = 0;
}
else {
f = (red == x) ? grn-blu : ((grn == x) ? blu-red : red-grn);
i = (red == x) ? 3 : ((grn == x) ? 5 : 1);
hue = fmod((i-f/(val-x))*60, 360);
sat = ((val-x)/val);
}
result.h = hue;
result.s = sat;
result.v = val;
return result;
}
/* ****************************************************************** */
int main(int argc, char * argv[]) {
int i, j, k, x, y;
gdImagePtr img;
int color;
HSV color_hsv;
RGB color_rgb;
float min_brightness = 255;
float max_brightness = 0;
/* **************************************************************** */
if (argc < 2) {
fprintf(stderr, "Error: No argument!\n");
return 1;
}
/* **************************************************************** */
for (k=1; k<argc; ++k) {
img = wczytajPng(argv[k]);
if (img == NULL) {
fprintf(stderr, "Error: Can't read %s!\n", argv[k]);
}
else {
x = gdImageSX(img);
y = gdImageSY(img);
/* find brightness range */
for (i=0; i<x; ++i) {
for (j=0; j<y; ++j) {
color = gdImageGetPixel(img, i, j);
color_hsv = rgb2hsv((float) gdImageRed(img, color),
(float) gdImageGreen(img, color),
(float) gdImageBlue(img, color));
min_brightness = MIN(min_brightness,color_hsv.v);
max_brightness = MAX(max_brightness,color_hsv.v);
}
}
/* normalize image brightness */
for (i=0; i<x; ++i) {
for (j=0; j<y; ++j) {
color = gdImageGetPixel(img, i, j);
color_hsv = rgb2hsv((float) gdImageRed(img, color),
(float) gdImageGreen(img, color),
(float) gdImageBlue(img, color));
color_hsv.v = (color_hsv.v - min_brightness) * (255. / (max_brightness - min_brightness));
color_rgb = hsv2rgb(color_hsv.h, color_hsv.s, color_hsv.v);
color = gdTrueColor((int) color_rgb.r,
(int) color_rgb.g,
(int) color_rgb.b);
gdImageSetPixel(img, i, j, color);
}
}
zapiszPng(img, argv[k]);
gdImageDestroy(img);
}
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment