gKit3
Loading...
Searching...
No Matches
image_io.cpp
1
2#include <cfloat>
3
4#include "color.h"
5#include "image.h"
6
7#define STB_IMAGE_IMPLEMENTATION
8#include "stb_image.h"
9
10#define STB_IMAGE_WRITE_IMPLEMENTATION
11#include "stb_image_write.h"
12
13
14Image srgb( const Image& image )
15{
16 Image tmp(image.width(), image.height());
17
18 for(unsigned i= 0; i < image.size(); i++)
19 tmp(i)= srgb(image(i));
20
21 return tmp;
22}
23
24Image linear( const Image& image )
25{
26 Image tmp(image.width(), image.height());
27
28 for(unsigned i= 0; i < image.size(); i++)
29 tmp(i)= linear(image(i));
30
31 return tmp;
32}
33
34float range( const Image& image )
35{
36 float gmin= FLT_MAX;
37 float gmax= 0;
38 for(unsigned i= 0; i < image.size(); i++)
39 {
40 Color color= image(i);
41 float g= color.r + color.g + color.b;
42
43 if(g < gmin) gmin= g;
44 if(g > gmax) gmax= g;
45 }
46
47 int bins[100] = {};
48 for(unsigned i= 0; i < image.size(); i++)
49 {
50 Color color= image(i);
51 float g= color.r + color.g + color.b;
52
53 int b= (g - gmin) * 100 / (gmax - gmin);
54 if(b >= 99) b= 99;
55 if(b < 0) b= 0;
56 bins[b]++;
57 }
58
59 float saturation= 0;
60 float qbins= 0;
61 for(unsigned i= 0; i < 100; i++)
62 {
63 qbins= qbins + float(bins[i]) / float(image.size());
64 if(qbins > .75f)
65 return gmin + float(i+1) / 100 * (gmax - gmin);
66 }
67
68 return gmax;
69}
70
71
72Image tone( const Image& image, const float saturation )
73{
74 Image tmp(image.width(), image.height());
75
76 float k= 1 / std::pow(saturation, 1 / 2.2f);
77 for(unsigned i= 0; i < image.size(); i++)
78 {
79 Color color= image(i);
80 if(std::isnan(color.r) || std::isnan(color.g) || std::isnan(color.b))
81 // marque les pixels pourris avec une couleur improbable...
82 color= Color(1, 0, 1);
83 else
84 // sinon transformation rgb -> srgb
85 color= k * srgb(color);
86
87 tmp(i)= Color(color, 1);
88 }
89
90 return tmp;
91}
92
93
94Image read_image( const char *filename, const bool flipY )
95{
96 stbi_ldr_to_hdr_scale(1.0f);
97 stbi_ldr_to_hdr_gamma(2.2f);
98 stbi_set_flip_vertically_on_load(flipY);
99
100 int width, height, channels;
101 float *data= stbi_loadf(filename, &width, &height, &channels, 4);
102 if(!data)
103 {
104 printf("[error] loading '%s'...\n", filename);
105 return {};
106 }
107
108 Image image(width, height);
109 for(unsigned i= 0, offset= 0; i < image.size(); i++, offset+= 4)
110 image(i)= Color( data[offset], data[offset + 1], data[offset + 2], data[offset + 3]);
111
112 stbi_image_free(data);
113 return image;
114}
115
116
117inline float clamp( const float x, const float min, const float max )
118{
119 if(x < min) return min;
120 else if(x > max) return max;
121 else return x;
122}
123
124bool write_image_png( const Image& image, const char *filename, const bool flipY )
125{
126 if(image.size() == 0)
127 return false;
128
129 std::vector<unsigned char> tmp(image.width()*image.height()*4);
130 for(unsigned i= 0, offset= 0; i < image.size(); i++, offset+= 4)
131 {
132 Color pixel= image(i) * 255;
133 tmp[offset ]= clamp(pixel.r, 0, 255);
134 tmp[offset +1]= clamp(pixel.g, 0, 255);
135 tmp[offset +2]= clamp(pixel.b, 0, 255);
136 tmp[offset +3]= clamp(pixel.a, 0, 255);
137 }
138
139 stbi_flip_vertically_on_write(flipY);
140 return stbi_write_png(filename, image.width(), image.height(), 4, tmp.data(), image.width() * 4) != 0;
141}
142
143bool write_image( const Image& image, const char *filename, const bool flipY )
144{
145 return write_image_png(image, filename, flipY );
146}
147
148bool write_image_bmp( const Image& image, const char *filename, const bool flipY )
149{
150 if(image.size() == 0)
151 return false;
152
153 std::vector<unsigned char> tmp(image.width()*image.height()*4);
154 for(unsigned i= 0, offset= 0; i < image.size(); i++, offset+= 4)
155 {
156 Color pixel= image(i) * 255;
157 tmp[offset ]= clamp(pixel.r, 0, 255);
158 tmp[offset +1]= clamp(pixel.g, 0, 255);
159 tmp[offset +2]= clamp(pixel.b, 0, 255);
160 tmp[offset +3]= clamp(pixel.a, 0, 255);
161 }
162
163 stbi_flip_vertically_on_write(flipY);
164 return stbi_write_bmp(filename, image.width(), image.height(), 4, tmp.data()) != 0;
165}
166
167bool write_image_hdr( const Image& image, const char *filename, const bool flipY )
168{
169 if(image.size() == 0)
170 return false;
171
172 stbi_flip_vertically_on_write(flipY);
173 return stbi_write_hdr(filename, image.width(), image.height(), 4, image.data()) != 0;
174}
175
176bool write_image_preview( const Image& image, const char *filename, const bool flipY )
177{
178 if(image.size() == 0)
179 return false;
180
181 Image tmp= tone(image, range(image));
182 return write_image_png(tmp, filename, flipY);
183}
184
representation d'une image.
Definition image.h:21
int height() const
renvoie la hauteur de l'image.
Definition image.h:102
unsigned size() const
renvoie le nombre de pixels de l'image.
Definition image.h:104
const float * data() const
renvoie un const pointeur sur le stockage des couleurs des pixels.
Definition image.h:86
int width() const
renvoie la largeur de l'image.
Definition image.h:100
bool write_image_png(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .png
Definition image_io.cpp:124
bool write_image_preview(const Image &image, const char *filename, const bool flipY)
raccourci pour write_image_png(tone(image, range(image)), "image.png")
Definition image_io.cpp:176
bool write_image_hdr(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .hdr
Definition image_io.cpp:167
bool write_image_bmp(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .bmp
Definition image_io.cpp:148
Image read_image(const char *filename, const bool flipY)
charge une image .bmp .tga .jpeg .png ou .hdr
Definition image_io.cpp:94
Image linear(const Image &image)
transformation couleur : srgb vers rgb lineaire
Definition image_io.cpp:24
bool write_image(const Image &image, const char *filename, const bool flipY)
enregistre une image au format .png
Definition image_io.cpp:143
float range(const Image &image)
evalue l'exposition d'une image.
Definition image_io.cpp:34
Image srgb(const Image &image)
transformation couleur : rgb lineaire vers srgb
Definition image_io.cpp:14
Image tone(const Image &image, const float saturation)
correction de l'exposition d'une image + transformation gamma.
Definition image_io.cpp:72
Point max(const Point &a, const Point &b)
renvoie la plus grande composante de chaque point. x, y, z= max(a.x, b.x), max(a.y,...
Definition vec.cpp:35
Point min(const Point &a, const Point &b)
renvoie la plus petite composante de chaque point. x, y, z= min(a.x, b.x), min(a.y,...
Definition vec.cpp:30
representation d'une couleur (rgba) transparente ou opaque.
Definition color.h:14