4 #include <stb_image_write.h>
11 float modulo(
double x,
double n)
20 unsigned char double_to_unsignedchar(
const double d)
22 return round(std::max(std::min(1., d), 0.) * 255);
29 assert(-size < x && x < 2 * size);
39 return size - 1 - (x - size) % size;
42 default:
return (x + size) % size;
50 auto size = std::max(w, h);
54 const auto sx =
static_cast<int>(std::floor(x - 0.5));
55 const auto sy =
static_cast<int>(std::floor(y - 0.5));
62 const std::function<
float(
const double&,
const double&)>& f,
71 for (
int i = 0; i < h; i++) {
72 for (
int j = 0; j < w; j++) {
74 u = (
static_cast<double>(j) + 0.5) /
static_cast<double>(w);
75 v = (
static_cast<double>(i) + 0.5) /
static_cast<double>(h);
86 wmtk::logger().trace(
"[save_image_hdr] start \"{}\"", path.string());
89 std::vector<float> buffer;
92 for (
auto i = 0; i < h; i++) {
93 for (
auto j = 0; j < w; j++) {
94 buffer[i * w + j] =
m_image(i, j);
97 if (path.extension() ==
".hdr") {
98 auto res = stbi_write_hdr(path.string().c_str(), w, h, 1, buffer.data());
100 }
else if (path.extension() ==
".exr") {
103 wmtk::logger().trace(
"[save_image_hdr] format doesn't support \"{}\"", path.string());
107 wmtk::logger().trace(
"[save_image] done \"{}\"", path.string());
114 const std::filesystem::path& path,
120 std::vector<float> buffer;
121 if (path.extension() ==
".exr") {
123 assert(!buffer.empty());
124 }
else if (path.extension() ==
".hdr") {
125 auto res = stbi_loadf(path.string().c_str(), &w, &h, &channels, 1);
126 buffer.assign(res, res + w * h);
128 wmtk::logger().trace(
"[load_image] format doesn't support \"{}\"", path.string());
134 for (
int i = 0, k = 0; i < h; i++) {
135 for (
int j = 0; j < w; j++) {
139 m_image.colwise().reverseInPlace();
149 Image low_res_image(h / 2, w / 2);
150 for (
int r = 0; r < h / 2; r++) {
151 for (
int c = 0; c < w / 2; c++) {
156 m_image(r * 2 + 1, c * 2 + 1)) /
160 return low_res_image;
164 double normalization_scale,
165 const Eigen::Matrix<double, 1, 3>& offset,
166 const std::filesystem::path& position_path,
167 const std::filesystem::path& normal_path,
168 const std::filesystem::path& height_path,
172 assert(std::filesystem::exists(position_path));
173 auto [w_p, h_p, index_red_p, index_green_p, index_blue_p, buffer_r_p, buffer_g_p, buffer_b_p] =
176 auto buffer_size = buffer_r_p.size();
177 std::vector<float> buffer_r_d(buffer_size);
178 std::vector<float> buffer_g_d(buffer_size);
179 std::vector<float> buffer_b_d(buffer_size);
181 if (std::filesystem::exists(normal_path) && std::filesystem::exists(height_path)) {
201 assert(buffer_r_p.size() == buffer_r_n.size());
202 assert(buffer_r_p.size() == buffer_r_h.size());
203 assert(buffer_r_p.size() == buffer_g_p.size());
204 assert(buffer_r_p.size() == buffer_b_p.size());
205 auto scale = [&](
float h) {
return min_height * (1.f - h) + max_height * h; };
207 for (
int i = 0; i < buffer_size; i++) {
208 buffer_r_d[i] = buffer_r_p[i] * normalization_scale +
209 scale(buffer_r_h[i]) * (2.0 * buffer_r_n[i] - 1.0) - offset[0];
210 buffer_g_d[i] = buffer_g_p[i] * normalization_scale +
211 scale(buffer_g_h[i]) * (2.0 * buffer_g_n[i] - 1.0) - offset[1];
212 buffer_b_d[i] = buffer_b_p[i] * normalization_scale +
213 scale(buffer_b_h[i]) * (2.0 * buffer_b_n[i] - 1.0) - offset[2];
217 wmtk::logger().info(
"No heightmap provided: using positions as displaced coordinates.");
219 for (
int i = 0; i < buffer_size; i++) {
220 buffer_r_d[i] = buffer_r_p[i] * normalization_scale - offset[0];
221 buffer_g_d[i] = buffer_g_p[i] * normalization_scale - offset[1];
222 buffer_b_d[i] = buffer_b_p[i] * normalization_scale - offset[2];
235 int w, h, channels, index_red, index_blue, index_green;
237 std::vector<float> buffer_r, buffer_g, buffer_b;
238 if (path.extension() ==
".exr") {
239 std::tie(w, h, index_red, index_green, index_blue, buffer_r, buffer_g, buffer_b) =
241 assert(!buffer_r.empty());
242 assert(!buffer_g.empty());
243 assert(!buffer_b.empty());
245 logger().error(
"[split_image] format doesn't support \"{}\"", path.string());
248 const std::filesystem::path directory = path.parent_path();
249 const std::string file = path.stem().string();
250 const std::filesystem::path path_r = directory / (file +
"_r.exr");
251 const std::filesystem::path path_g = directory / (file +
"_g.exr");
252 const std::filesystem::path path_b = directory / (file +
"_b.exr");
265 for (
int i = 0, k = 0; i < h; i++) {
266 for (
int j = 0; j < w; j++) {
267 image.
set(h - i - 1, j, buffer[k++]);
275 int w, h, channels, index_red, index_blue, index_green;
277 std::vector<float> buffer_r, buffer_g, buffer_b;
278 if (path.extension() ==
".exr") {
279 std::tie(w, h, index_red, index_green, index_blue, buffer_r, buffer_g, buffer_b) =
281 assert(!buffer_r.empty());
282 assert(!buffer_g.empty());
283 assert(!buffer_b.empty());
285 wmtk::logger().error(
"[load_rgb_image] format doesn't support \"{}\"", path.string());
int get_coordinate(const int x, const WrappingMode mode) const
Image down_sample() const
void load(const std::filesystem::path &path, WrappingMode mode_x, WrappingMode mode_y)
void set_wrapping_mode(WrappingMode mode_x, WrappingMode mode_y)
std::pair< int, int > get_pixel_index(const double &u, const double &v) const
bool save(const std::filesystem::path &path) const
bool set(const std::function< float(const double &, const double &)> &f, const WrappingMode mode_x=WrappingMode::CLAMP_TO_EDGE, const WrappingMode mode_y=WrappingMode::CLAMP_TO_EDGE)
auto load_image_exr_red_channel(const std::filesystem::path &path) -> std::tuple< size_t, size_t, std::vector< float >>
auto load_image_exr_split_3channels(const std::filesystem::path &path) -> std::tuple< size_t, size_t, int, int, int, std::vector< float >, std::vector< float >, std::vector< float >>
std::array< Image, 3 > load_rgb_image(const std::filesystem::path &path)
std::array< Image, 3 > combine_position_normal_texture(double normalization_scale, const Eigen::Matrix< double, 1, 3 > &offset, const std::filesystem::path &position_path, const std::filesystem::path &normal_path, const std::filesystem::path &height_path, float min_height, float max_height)
Image buffer_to_image(const std::vector< float > &buffer, int w, int h)
bool save_image_exr_red_channel(size_t width, size_t height, const std::vector< float > &data, const std::filesystem::path &path)
void split_and_save_3channels(const std::filesystem::path &path)
spdlog::logger & logger()
Retrieves the current logger.