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