Introduce templatized bitmap class
All checks were successful
Build ptprnt / build (push) Successful in 5m11s
All checks were successful
Build ptprnt / build (push) Successful in 5m11s
This commit is contained in:
@@ -17,6 +17,21 @@
|
||||
|
||||
*/
|
||||
|
||||
/**
|
||||
* @file Bitmap.hpp
|
||||
* @brief Template-based bitmap image representation supporting multiple pixel formats.
|
||||
*
|
||||
* This file defines a flexible Bitmap class that can work with various pixel formats
|
||||
* including grayscale (ALPHA8) and color formats (RGBX8, RGBA8, ARGB8). The implementation
|
||||
* uses C++ templates to provide type-safe bitmap operations while maintaining efficiency.
|
||||
*
|
||||
* The bitmap data is stored in row-major order, making it compatible with common image
|
||||
* processing libraries and suitable for label printing operations.
|
||||
*
|
||||
* @author Moritz Martinius
|
||||
* @date 2023-2025
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <cstdint>
|
||||
@@ -24,37 +39,165 @@
|
||||
|
||||
namespace ptprnt::graphics {
|
||||
|
||||
using ALPHA8 = std::uint8_t; // Alpha only, 8 bit per pixel
|
||||
using RGBX8 = std::uint32_t; // RGB, least significant byte unused, 8 bit per channel
|
||||
using RGBA8 = std::uint32_t; // RGB, least significant byte alpha, 8 bit per channel
|
||||
using ARGB8 = std::uint32_t; // RGB, most significant byte alpha, 8 bit per channel
|
||||
/**
|
||||
* @brief Pixel format with 8-bit alpha channel only.
|
||||
*
|
||||
* Single byte per pixel representing opacity/transparency.
|
||||
* Used for grayscale and monochrome image processing.
|
||||
*/
|
||||
using ALPHA8 = std::uint8_t;
|
||||
|
||||
/**
|
||||
* @brief Pixel format with RGB channels and unused byte (32-bit).
|
||||
*
|
||||
* Format: [unused:8][R:8][G:8][B:8] (least significant byte unused)
|
||||
* Each color channel is 8 bits, total 32 bits per pixel.
|
||||
*/
|
||||
using RGBX8 = std::uint32_t;
|
||||
|
||||
/**
|
||||
* @brief Pixel format with RGB channels and alpha (32-bit).
|
||||
*
|
||||
* Format: [A:8][R:8][G:8][B:8] (least significant byte is alpha)
|
||||
* Each channel is 8 bits, total 32 bits per pixel.
|
||||
*/
|
||||
using RGBA8 = std::uint32_t;
|
||||
|
||||
/**
|
||||
* @brief Pixel format with alpha and RGB channels (32-bit).
|
||||
*
|
||||
* Format: [A:8][R:8][G:8][B:8] (most significant byte is alpha)
|
||||
* Each channel is 8 bits, total 32 bits per pixel.
|
||||
*/
|
||||
using ARGB8 = std::uint32_t;
|
||||
|
||||
/**
|
||||
* @brief Template-based bitmap class for various pixel formats.
|
||||
*
|
||||
* A flexible bitmap implementation supporting multiple pixel formats through
|
||||
* template specialization. The class manages a 2D array of pixels stored in
|
||||
* row-major order (top to bottom, left to right).
|
||||
*
|
||||
* @tparam T Pixel format type (ALPHA8, RGBX8, RGBA8, or ARGB8)
|
||||
*
|
||||
* @note Explicitly instantiated for ALPHA8 and RGBX8 formats.
|
||||
*
|
||||
* Example usage:
|
||||
* @code
|
||||
* Bitmap<ALPHA8> grayscaleBitmap(100, 50);
|
||||
* std::vector<ALPHA8> pixels(100 * 50, 128);
|
||||
* grayscaleBitmap.setPixels(pixels);
|
||||
* @endcode
|
||||
*/
|
||||
template <class T>
|
||||
class Bitmap {
|
||||
public:
|
||||
/**
|
||||
* @brief Constructs a new bitmap with specified dimensions.
|
||||
*
|
||||
* Creates a bitmap with the given width and height. All pixels are
|
||||
* initialized to their default value (typically 0).
|
||||
*
|
||||
* @param width Width of the bitmap in pixels
|
||||
* @param height Height of the bitmap in pixels
|
||||
*/
|
||||
Bitmap(uint16_t width, uint16_t height);
|
||||
|
||||
/**
|
||||
* @brief Default destructor.
|
||||
*/
|
||||
~Bitmap() = default;
|
||||
|
||||
/**
|
||||
* @brief Copy constructor (default).
|
||||
*/
|
||||
Bitmap(const Bitmap&) = default;
|
||||
|
||||
/**
|
||||
* @brief Copy assignment operator (default).
|
||||
*/
|
||||
Bitmap& operator=(const Bitmap&) = default;
|
||||
|
||||
/**
|
||||
* @brief Move constructor (default).
|
||||
*/
|
||||
Bitmap(Bitmap&&) = default;
|
||||
|
||||
/**
|
||||
* @brief Move assignment operator (default).
|
||||
*/
|
||||
Bitmap& operator=(Bitmap&&) = default;
|
||||
|
||||
/**
|
||||
* @brief Gets the width of the bitmap.
|
||||
*
|
||||
* @return Width in pixels
|
||||
*/
|
||||
[[nodiscard]] uint16_t getWidth() const;
|
||||
|
||||
/**
|
||||
* @brief Gets the height of the bitmap.
|
||||
*
|
||||
* @return Height in pixels
|
||||
*/
|
||||
[[nodiscard]] uint16_t getHeight() const;
|
||||
|
||||
/**
|
||||
* @brief Sets the pixel data for the entire bitmap.
|
||||
*
|
||||
* Replaces all pixel data with the provided vector. The vector size
|
||||
* must match width * height.
|
||||
*
|
||||
* @param pixels Vector of pixel values in row-major order
|
||||
* @return true if pixels were successfully set, false if size mismatch
|
||||
*/
|
||||
bool setPixels(const std::vector<T>& pixels);
|
||||
|
||||
/**
|
||||
* @brief Gets a copy of all pixel data.
|
||||
*
|
||||
* Returns a complete copy of the internal pixel buffer in row-major order.
|
||||
*
|
||||
* @return Vector containing a copy of all pixels
|
||||
*/
|
||||
[[nodiscard]] std::vector<T> getPixelsCpy() const;
|
||||
|
||||
/**
|
||||
* @brief Extracts a horizontal line (row) of pixels.
|
||||
*
|
||||
* Returns a copy of all pixels in the specified row.
|
||||
*
|
||||
* @param line Row index (0-based, 0 is top)
|
||||
* @return Vector containing pixels from the specified line
|
||||
*/
|
||||
[[nodiscard]] std::vector<T> getLine(uint16_t line) const;
|
||||
|
||||
/**
|
||||
* @brief Extracts a vertical column of pixels.
|
||||
*
|
||||
* Returns a copy of all pixels in the specified column.
|
||||
*
|
||||
* @param col Column index (0-based, 0 is left)
|
||||
* @return Vector containing pixels from the specified column
|
||||
*/
|
||||
[[nodiscard]] std::vector<T> getCol(uint16_t col) const;
|
||||
|
||||
/**
|
||||
* @brief Prints a visual representation of the bitmap to stdout.
|
||||
*
|
||||
* Outputs an ASCII representation of the bitmap for debugging purposes.
|
||||
* The visualization depends on the pixel format and values.
|
||||
*/
|
||||
void visualize() const;
|
||||
|
||||
private:
|
||||
uint16_t mWidth;
|
||||
uint16_t mHeight;
|
||||
std::vector<T> mPixels;
|
||||
uint16_t mWidth; ///< Width of the bitmap in pixels
|
||||
uint16_t mHeight; ///< Height of the bitmap in pixels
|
||||
std::vector<T> mPixels; ///< Pixel data stored in row-major order (top to bottom, left to right)
|
||||
};
|
||||
|
||||
// force compiler to generate class for type ALPHA8 and RGBX8
|
||||
// Explicit template instantiations to force compiler to generate class implementations
|
||||
// for the most commonly used pixel formats
|
||||
template class Bitmap<ALPHA8>;
|
||||
template class Bitmap<RGBX8>;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user