This class represents bitmap/image/texture in system memory where each point/pixel is represented as 4-component RGBA value.
When using []
operators be sure what exactly you are doing. When using constant image(for example, declared as const Image bmp
) operator will be the constant one as well. When using non-constant image(for example, declared as Image bmp
) operator will be non-constant one. There is difference between constant and non-constant []
operators. Constant one uses constant pointer to image data. In most cases it is absolutely the same as non-constant one. But there is one case when there is difference. This case takes place when using inline image data. In this case image is considered as constant indestructible one. It also means it is unchangeable and thus in this case non-constant []
operator cannot be used. Using such an image is usually okay, if you do it right, and won't result in any error unless you try to use it incorrectly and especially in combination with another image created base on the first one using moving constructor or moving assignment operator. Consider following example:
const Color data[2 * 1]{ CColors::Red, CColors::Green }; // Inline image dataImage a{ 2, 1, data }; // Create indestructible image...
if (a[0][0] == CColors::Red) // Check whether left-top pixel has red color{
...
}
At first the code looks well. It is even compiled without errors or warnings. But it won't work. There will be runtime error at the if line. The error here is declaring image a as non-constant one. In this case non-constant []
operator will be used and result in fatal error. The solution is quiet simple. All you need in this case is to declare image a as constant one: const Image a{ 2, 1, data };
So, whenever you use constant inline data in images, you would better declare such images as constant ones.
But it is not always possible to declare image as constant one. In this case we recommend not to use []
operator but to use getPixel()
methods instead.
You can find more information in comments below.
// All drawing operations SHOULDN'T include last points(right and bottom edges)
class Image
{
public:
int const &Width;
int const &Height;
const Color* const &Data;
Image(); // Create empty
Image(const int w, const int h); // Create with specified size
Image(const int w, const int h, const Color *data); // Create with specified size and data.
Image(const Image &other); // Copy
Image(Image &&other); // Move
~Image(); // Destructor
const COLUMN &operator[](const int x) const; // Return bitmap column. You can access pixel as bmp[x][y]. This is the fastest access pixel method but it is unsafe, so be sure you are not accessing pixel outside of bitmap
COLUMN &operator[](const int x); // Return bitmap column. You can access pixel as bmp[x][y]. This is the fastest access pixel method but it is unsafe, so be sure you are not accessing pixel outside of bitmap
Image &operator=(const Image &other); // Copy
Image &operator=(Image &&other); // Move
bool operator==(const Image &other) const; // Check if bitmaps are equal
bool operator!=(const Image &other) const; // Check if bitmaps are not equal
Color getPixel(const int x, const int y) const; // Return pixel from specified position. It is safe method of accessing pixel as it checks whether specified coordinates are inside the bitmap. If bitmap is empty, zero pixel will be returned. If coordinates are outside the bitmap, nearest border pixel will be returned. This method is slower than corresponding operators because it check coordinates first
Color getPixel(const int x, const int y, const Color &def) const; // Return pixel from specified position or def one if position is outside the bitmap
const bool isEmpty() const; // Check whether it is empty
bool setWidth(const int value); // Set width
bool setHeight(const int value); // Set height
bool setSize(const int w, const int h); // Set size
bool setPixel(const int x, const int y, const Color &value); // Set pixel at specified position. It is safe method for setting pixel as it checks whether specified coordinates are inside the bitmap. If coordinates are invalid, no changes will be made. This method is slower than corresponding operators because it check coordinates first
bool setData(const int w, const int h, const Color *data); // Set size and data
};
Following operator is also available.
std::wostream &operator<<(std::wostream &stream, const Image &a); // Output as source code
Namespace: | nitisa |
Include: | Nitisa/Image/Image.h |