9#define STB_IMAGE_IMPLEMENTATION
12#define STB_IMAGE_WRITE_IMPLEMENTATION
13#include "stb_image_write.h"
17 Image tmp(image.width(), image.height());
19 for(
unsigned i= 0; i < image.size(); i++)
20 tmp(i)=
srgb(image(i));
27 Image tmp(image.width(), image.height());
29 for(
unsigned i= 0; i < image.size(); i++)
35float range(
const Image& image )
39 for(
unsigned i= 0; i < image.size(); i++)
41 Color color= image(i);
42 float g= color.r + color.g + color.b;
49 for(
unsigned i= 0; i < image.size(); i++)
51 Color color= image(i);
52 float g= color.r + color.g + color.b;
54 int b= (g - gmin) * 100 / (gmax - gmin);
62 for(
unsigned i= 0; i < 100; i++)
64 qbins= qbins + float(bins[i]) / float(image.size());
66 return gmin + float(i+1) / 100 * (gmax - gmin);
72Image tone(
const Image& image,
const float saturation )
74 Image tmp(image.width(), image.height());
76 float k= 1 / std::pow(saturation, 1 / 2.2f);
77 for(
unsigned i= 0; i < image.size(); i++)
79 Color color= image(i);
80 if(std::isnan(color.r) || std::isnan(color.g) || std::isnan(color.b))
82 color=
Color(1, 0, 1);
85 color= k *
srgb(color);
87 tmp(i)=
Color(color, 1);
96 unsigned w= std::max(
unsigned(1), image.width() / 2);
97 unsigned h= std::max(
unsigned(1), image.height() / 2);
101 for(
unsigned py= 0; py < h; py++)
102 for(
unsigned px= 0; px < w; px++)
106 tmp(px, py)= (image(x, y) + image(x +1, y) + image(x +1, y +1) + image(x, y +1)) / 4;
115 Image flip(image.width(), image.height());
117 for(
unsigned y= 0; y < image.height(); y++)
118 for(
unsigned x= 0; x < image.width(); x++)
120 unsigned s= image.offset(x, y);
131 Image flip(image.width(), image.height());
133 for(
unsigned y= 0; y < image.height(); y++)
134 for(
unsigned x= 0; x < image.width(); x++)
136 unsigned s= image.offset(x, y);
145Image copy(
const Image& image,
const unsigned xmin,
const unsigned ymin,
const unsigned width,
const unsigned height )
149 for(
unsigned y= 0; y < height; y++)
150 for(
unsigned x= 0; x < width; x++)
152 unsigned s= image.offset(xmin+x, ymin+y);
153 unsigned d=
copy.offset(x, y);
165 if(!stbi_info(filename, &w, &h, &c))
168 return sizeof(
Color)*w*h;
173 stbi_ldr_to_hdr_scale(1);
174 stbi_ldr_to_hdr_gamma(1);
175 stbi_set_flip_vertically_on_load(
flipY);
177 int width, height, channels;
178 float *data= stbi_loadf(filename, &width, &height, &channels, 4);
181 printf(
"[error] loading '%s'...\n", filename);
185 Image image(width, height);
186 for(
unsigned i= 0, offset= 0; i < image.size(); i++, offset+= 4)
187 image(i)=
Color( data[offset], data[offset + 1], data[offset + 2], data[offset + 3]);
189 stbi_image_free(data);
193Image read_image_hdr(
const char *filename,
const bool flipY )
199inline float clamp(
const float x,
const float min,
const float max )
202 else if(x >
max)
return max;
208 if(image.size() == 0)
211 std::vector<unsigned char> tmp(image.width()*image.height()*4);
212 for(
unsigned i= 0, offset= 0; i < image.size(); i++, offset+= 4)
214 Color pixel= image(i) * 255;
215 tmp[offset ]= clamp(pixel.r, 0, 255);
216 tmp[offset +1]= clamp(pixel.g, 0, 255);
217 tmp[offset +2]= clamp(pixel.b, 0, 255);
218 tmp[offset +3]= clamp(pixel.a, 0, 255);
221 stbi_flip_vertically_on_write(
flipY);
222 return stbi_write_png(filename, image.width(), image.height(), 4, tmp.data(), image.width() * 4) != 0;
232 if(image.size() == 0)
235 std::vector<unsigned char> tmp(image.width()*image.height()*4);
236 for(
unsigned i= 0, offset= 0; i < image.size(); i++, offset+= 4)
238 Color pixel= image(i) * 255;
239 tmp[offset ]= clamp(pixel.r, 0, 255);
240 tmp[offset +1]= clamp(pixel.g, 0, 255);
241 tmp[offset +2]= clamp(pixel.b, 0, 255);
242 tmp[offset +3]= clamp(pixel.a, 0, 255);
245 stbi_flip_vertically_on_write(
flipY);
246 return stbi_write_bmp(filename, image.width(), image.height(), 4, tmp.data()) != 0;
251 if(image.size() == 0)
254 stbi_flip_vertically_on_write(
flipY);
255 return stbi_write_hdr(filename, image.width(), image.height(), 4, image.data()) != 0;
260 if(image.size() == 0)
263 Image tmp= tone(image, range(image));
268ImageData image_data(
unsigned char *data,
const int width,
const int height,
const int channels )
270 int n= std::max(3, channels);
275 for(
int i= 0; i < width*height*4; i+= 4)
277 image.pixels[i]= data[i];
278 image.pixels[i+1]= data[i+1];
279 image.pixels[i+2]= data[i+2];
280 image.pixels[i+3]= data[i+3];
283 else if(channels == 3)
285 for(
int i= 0; i < width*height*3; i+= 3)
287 image.pixels[i]= data[i];
288 image.pixels[i+1]= data[i+1];
289 image.pixels[i+2]= data[i+2];
295 for(
int i= 0; i < width*height*3; i+= 3)
301 if(n >= 1) { r= data[k++]; g= r; b= r; }
302 if(n >= 2) { g= data[k++]; b= 0; }
303 if(n >= 3) { b= data[k++]; }
306 image.pixels[i+1]= g;
307 image.pixels[i+2]= b;
311 stbi_image_free(data);
317 stbi_set_flip_vertically_on_load(
flipY);
319 int width, height, channels;
320 unsigned char *data= stbi_load_from_memory((
const unsigned char *) buffer, size, &width, &height, &channels, 0);
323 printf(
"[error] reading buffer image...\n");
327 return image_data(data, width, height, channels);
332 stbi_set_flip_vertically_on_load(
flipY);
334 int width, height, channels;
335 unsigned char *data= stbi_load(filename, &width, &height, &channels, 0);
338 printf(
"[error] loading '%s'...\n", filename);
342 return image_data(data, width, height, channels);
350 printf(
"[error] writing color image '%s'... not an 8 bits image.\n", filename);
354 stbi_flip_vertically_on_write(
flipY);
357 if(std::string(filename).rfind(
".png") != std::string::npos)
358 code= stbi_write_png(filename, image.width, image.height, image.channels, image.pixels.data(), image.width * image.channels) != 0;
359 else if(std::string(filename).rfind(
".bmp") != std::string::npos)
360 code= stbi_write_bmp(filename, image.width, image.height, image.channels, image.pixels.data()) != 0;
364 printf(
"[error] writing color image '%s'... not a .png / .bmp image.\n", filename);
371 printf(
"[error] writing color image '%s'...\n", filename);
379 ImageData flip(image.width, image.height, image.channels);
381 for(
unsigned y= 0; y < image.height; y++)
382 for(
unsigned x= 0; x < image.width; x++)
384 unsigned s= image.offset(x, y);
385 unsigned d= flip.offset(x, flip.height - y -1);
387 for(
unsigned i= 0; i < image.channels; i++)
388 flip.pixels[d +i]= image.pixels[s +i];
396 ImageData flip(image.width, image.height, image.channels);
398 for(
unsigned y= 0; y < image.height; y++)
399 for(
unsigned x= 0; x < image.width; x++)
401 unsigned s= image.offset(x, y);
402 unsigned d= flip.offset(flip.width -x -1, y);
404 for(
unsigned i= 0; i < image.channels; i++)
405 flip.pixels[d +i]= image.pixels[s +i];
411ImageData copy(
const ImageData& image,
const unsigned xmin,
const unsigned ymin,
const unsigned width,
const unsigned height )
415 for(
unsigned y= 0; y < height; y++)
416 for(
unsigned x= 0; x < width; x++)
418 unsigned s= image.offset(xmin +x, ymin +y);
419 unsigned d=
copy.offset(x, y);
421 for(
unsigned i= 0; i < image.channels; i++)
422 copy.pixels[d +i]= image.pixels[s +i];
430 unsigned w= std::max(
unsigned(1), image.width / 2);
431 unsigned h= std::max(
unsigned(1), image.height / 2);
435 for(
unsigned py= 0; py < h; py++)
436 for(
unsigned px= 0; px < w; px++)
440 unsigned d= tmp.offset(px, py);
442 for(
unsigned i= 0; i < image.channels; i++)
444 image.pixels[image.offset(x, y) +i]
445 + image.pixels[image.offset(x+1, y) +i]
446 + image.pixels[image.offset(x, y+1) +i]
447 + image.pixels[image.offset(x+1, y+1) +i] ) / 4;
458 while(w > 1 || h > 1)
460 w= std::max(1, w / 2);
461 h= std::max(1, h / 2);
representation d'une image.
unsigned width() const
renvoie la largeur de l'image.
unsigned height() const
renvoie la hauteur de l'image.
unsigned offset(const int x, const int y) const
void printf(Text &text, const int px, const int py, const char *format,...)
affiche un texte a la position x, y. meme utilisation que printf().
bool write_image_png(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .png
bool write_image_preview(const Image &image, const char *filename, const bool flipY)
raccourci pour write_image_png(tone(image, range(image)), "image.png")
bool write_image_hdr(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .hdr
unsigned read_image_size(const char *filename)
renvoie la taille en octets de l'image chargee. ou 0 si erreur.
bool write_image_bmp(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .bmp
Image mipmap(const Image &image)
reduit une image.
Image flipY(const Image &image)
retourne l'image
Image flipX(const Image &image)
retourne l'image
Image read_image(const char *filename, const bool flipY)
int write_image_data(ImageData &image, const char *filename, const bool flipY)
enregistre des donnees dans un fichier png.
Image linear(const Image &image)
transformation couleur : srgb vers rgb lineaire
ImageData read_image_data(const void *buffer, const unsigned size, const bool flipY)
charge les donnees d'un fichier png stocke en memoire. renvoie une image initialisee par defaut en ca...
bool write_image(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .png
Image copy(const Image &image, const unsigned xmin, const unsigned ymin, const unsigned width, const unsigned height)
renvoie un bloc de l'image
int miplevels(const int width, const int height)
renvoie le nombre de mipmap d'une image width x height.
Image srgb(const Image &image)
transformation couleur : rgb lineaire vers srgb
Point max(const Point &a, const Point &b)
renvoie la plus grande composante de chaque point { max(a.x, b.x), max(a.y, b.y), max(a....
Point min(const Point &a, const Point &b)
renvoie la plus petite composante de chaque point { min(a.x, b.x), min(a.y, b.y), min(a....
representation d'une couleur (rgba) transparente ou opaque.
stockage temporaire des donnees d'une image.