A tool to construct HDR-images from a series of exposures.

image.cpp 2.9KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. #include <stdio.h>
  2. #include <iostream>
  3. #include <fstream>
  4. #include <sstream>
  5. #include <vector>
  6. #define STB_IMAGE_IMPLEMENTATION
  7. #include "stb_image.h"
  8. #include "image.h"
  9. #include "exif.h"
  10. using namespace std;
  11. using namespace haader;
  12. Image::Image():
  13. m_width(0),
  14. m_height(0),
  15. m_components(0),
  16. m_exposure_time(0.0)
  17. {
  18. }
  19. void Image::to_string(string &s) const {
  20. stringstream ss;
  21. ss << "Image(";
  22. ss << m_width << 'x' << m_height << 'x' << m_components << ")";
  23. s = ss.str();
  24. }
  25. bool Image::read_from_file(const char *file_path) {
  26. int x = 0;
  27. int y = 0;
  28. int components = 0;
  29. unsigned char *data = stbi_load(file_path, &x, &y, &components, 0);
  30. if (data) {
  31. m_width = x;
  32. m_height = y;
  33. m_components = components;
  34. size_t size = (size_t)x * (size_t)y * (size_t)components;
  35. m_image_data.assign(data, data + size);
  36. // try to read EXIF data
  37. {
  38. ExifTags tags;
  39. ifstream stream;
  40. stream.open(file_path);
  41. if (stream.is_open() and ExifTags::read_from_jpeg(stream, tags)) {
  42. if (tags.get_exposure_time(m_exposure_time)) {
  43. cout << "Exposure time: " << m_exposure_time << " sec" << endl;
  44. }
  45. }
  46. }
  47. return true;
  48. } else {
  49. cerr << "Can not read \"" << file_path << "\" as an image." << endl;
  50. return false;
  51. }
  52. stbi_image_free(data);
  53. }
  54. bool Image::save_as_ppm_file(const char *file_path, bool ascii) const {
  55. if (ascii) {
  56. // ASCII
  57. ofstream out(file_path);
  58. out << "P3\n";
  59. out << m_width << ' ' << m_height << '\n';
  60. out << "255\n";
  61. unsigned int pixels = m_width * m_height;
  62. unsigned int index = 0;
  63. for (unsigned int i = 0; i < pixels; i++) {
  64. out << (int)m_image_data[index] << ' ' << (int)m_image_data[index + 1] << ' ' << (int)m_image_data[index + 2] << '\n';
  65. index += 3;
  66. }
  67. out.close();
  68. return true;
  69. } else {
  70. // binary
  71. ofstream out(file_path);
  72. out << "P6\n";
  73. out << m_width << ' ' << m_height << '\n';
  74. out << "255\n";
  75. unsigned int pixels = m_width * m_height;
  76. unsigned int index = 0;
  77. for (unsigned int i = 0; i < pixels; i++) {
  78. out << m_image_data[index] << m_image_data[index + 1] << m_image_data[index + 2];
  79. index += 3;
  80. }
  81. out.close();
  82. return true;
  83. }
  84. }
  85. unsigned int Image::get_width() const {
  86. return m_width;
  87. }
  88. unsigned int Image::get_height() const {
  89. return m_height;
  90. }
  91. unsigned int Image::get_components() const {
  92. return m_components;
  93. }
  94. bool Image::has_equal_dimensions(const Image &other) const {
  95. return (m_width == other.m_width &&
  96. m_height == other.m_height &&
  97. m_components == other.m_components);
  98. }
  99. double Image::get_exposure_time() const {
  100. return m_exposure_time;
  101. }