Img2Num C++ (Internal Developer Docs)  dev
API Documentation
Image.h
1 #ifndef IMAGE_H
2 #define IMAGE_H
3 
4 #include <algorithm>
5 #include <stdexcept>
6 #include <type_traits>
7 #include <vector>
8 
9 #include "internal/Pixel.h"
10 #include "internal/PixelConverter.h"
11 
12 namespace ImageLib {
13 template <typename PixelT>
14 class Image {
15  static_assert(std::is_base_of_v<Pixel<typename PixelT::value_type /*NumberT*/>, PixelT>,
16  "Image<PixelT>: PixelT must derive from Pixel<NumberT>");
17 
18  public:
19  Image() : width(0), height(0) {
20  }
21  Image(int width, int height, PixelT fill = PixelT())
22  : width(width), height(height), data(width * height, fill) {
23  }
24 
25  template <typename ConverterT>
26  void loadFromBuffer(const uint8_t *buffer, int width, int height,
27  PixelConverter<ConverterT> converter) {
28  // converter.convert must return exactly PixelT
29  static_assert(std::is_same_v<decltype(converter.convert((const uint8_t *)nullptr)), PixelT>,
30  "Converter return type must match PixelT");
31 
32  this->width = width;
33  this->height = height;
34  const int pixelCount = getPixelCount();
35  data.resize(pixelCount);
36  for (int i = 0; i < pixelCount; ++i) {
37  data[i] = converter.convert(&buffer[i * converter.bytesPerPixel]);
38  }
39  }
40 
41  void fill(const PixelT &color) {
42  std::fill(data.begin(), data.end(), color);
43  }
44 
45  using iter = typename std::vector<PixelT>::iterator;
46  iter begin() {
47  return data.begin();
48  }
49  iter end() {
50  return data.end();
51  }
52  using const_iter = typename std::vector<PixelT>::const_iterator;
53  const_iter begin() const {
54  return data.begin();
55  }
56  const_iter end() const {
57  return data.end();
58  }
59 
60  int getWidth() const {
61  return width;
62  }
63  int getHeight() const {
64  return height;
65  }
66  int getPixelCount() const {
67  return width * height;
68  }
69  int getSize() const {
70  return getPixelCount();
71  }
72 
73  const std::vector<PixelT> &getData() const {
74  return data;
75  }
76 
77  const PixelT &getPixel(int x, int y) const {
78  return data[index(x, y)];
79  }
80  PixelT &getPixel(int x, int y) {
81  return data[index(x, y)];
82  }
83 
84  void setPixel(int x, int y, const PixelT &p) {
85  data[index(x, y)] = p;
86  }
87 
88  // Operator[] for flat indexing
89  PixelT &operator[](int idx) {
90  return data.at(idx);
91  } // set
92  const PixelT &operator[](int idx) const {
93  return data.at(idx);
94  } // get
95 
96  // Operator() for (x, y) access
97  PixelT &operator()(int x, int y) {
98  return data.at(index(x, y));
99  } // set
100  const PixelT &operator()(int x, int y) const {
101  return data.at(index(x, y));
102  } // get
103 
104  private:
105  std::vector<PixelT> data;
106  int width, height;
107 
108  int index(int x, int y) const {
109  if (x < 0 || y < 0 || x >= width || y >= height)
110  throw std::out_of_range("Pixel coordinates out of bounds");
111  return y * width + x;
112  }
113 };
114 } // namespace ImageLib
115 
116 #endif