From ac1aba54a00d42c541094393f91240349a4ae249 Mon Sep 17 00:00:00 2001 From: Ali Ozer Tekin <74454719+aliozertekin@users.noreply.github.com> Date: Fri, 31 Jan 2025 03:13:54 +0300 Subject: [PATCH 1/2] fixed rotation handling, up to date --- README.md | 51 ++++++++++++++++ examples/rotation.cpp | 38 ++++++++++++ images/rotated/penguin_flipped_h.bmp | Bin 0 -> 260118 bytes images/rotated/penguin_flipped_v.bmp | Bin 0 -> 260118 bytes images/rotated/penguin_rotated_left.bmp | Bin 0 -> 259502 bytes images/rotated/penguin_rotated_right.bmp | Bin 0 -> 259502 bytes lib/include/BitmapPlusPlus.hpp | 71 ++++++++++++++++++++++- 7 files changed, 159 insertions(+), 1 deletion(-) create mode 100644 examples/rotation.cpp create mode 100644 images/rotated/penguin_flipped_h.bmp create mode 100644 images/rotated/penguin_flipped_v.bmp create mode 100644 images/rotated/penguin_rotated_left.bmp create mode 100644 images/rotated/penguin_rotated_right.bmp diff --git a/README.md b/README.md index 5a2d5db..bb1bdda 100644 --- a/README.md +++ b/README.md @@ -236,6 +236,57 @@ int main(void) { ![modified-penguin](images/modified-penguin.bmp) +

+Rotate, Flip The Penguin +
+ +```cpp +#include "BitmapPlusPlus.hpp" +#include + +int main(void) { + try { + bmp::Bitmap image; + + // Load the original bitmap + image.load("penguin.bmp"); + + // Test vertical flip + bmp::Bitmap flipped_v = image.flip_v(); + flipped_v.save("rotated/penguin_flipped_v.bmp"); + std::cout << "Vertical flip saved as penguin_flipped_v.bmp" << std::endl; + + // Test horizontal flip + bmp::Bitmap flipped_h = image.flip_h(); + flipped_h.save("rotated/penguin_flipped_h.bmp"); + std::cout << "Horizontal flip saved as penguin_flipped_h.bmp" << std::endl; + + // Test rotate 90 degrees to the right + bmp::Bitmap rotated_right = image.rotate_90_right(); + rotated_right.save("rotated/penguin_rotated_right.bmp"); + std::cout << "Rotated 90 degrees right saved as penguin_rotated_right.bmp" << std::endl; + + // Test rotate 90 degrees to the left + bmp::Bitmap rotated_left = image.rotate_90_left(); + rotated_left.save("rotated/penguin_rotated_left.bmp"); + std::cout << "Rotated 90 degrees left saved as penguin_rotated_left.bmp" << std::endl; + + return EXIT_SUCCESS; + } + catch (const bmp::Exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + return EXIT_FAILURE; + } +} + +``` +![penguin](images/penguin.bmp) +![penguin_flipped_v](images/rotated/penguin_flipped_v.bmp) +![penguin_flipped_h](images/rotated/penguin_flipped_h.bmp) +![penguin_rotated_right](images/rotated/penguin_rotated_right.bmp) +![penguin_rotated_left](images/rotated/penguin_rotated_left.bmp) + +

Chess Board diff --git a/examples/rotation.cpp b/examples/rotation.cpp new file mode 100644 index 0000000..33f30bf --- /dev/null +++ b/examples/rotation.cpp @@ -0,0 +1,38 @@ +#include "BitmapPlusPlus.hpp" +#include + +int main(void) { + try { + bmp::Bitmap image; + + // Load the original bitmap + image.load(std::filesystem::path(ROOT_DIR) / "images" / "penguin.bmp"); + + // Test vertical flip + bmp::Bitmap flipped_v = image.flip_v(); + flipped_v.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_v.bmp"); + std::cout << "Vertical flip saved as penguin_flipped_v.bmp" << std::endl; + + // Test horizontal flip + bmp::Bitmap flipped_h = image.flip_h(); + flipped_h.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_h.bmp"); + std::cout << "Horizontal flip saved as penguin_flipped_h.bmp" << std::endl; + + // Test rotate 90 degrees to the right + bmp::Bitmap rotated_right = image.rotate_90_right(); + rotated_right.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_right.bmp"); + std::cout << "Rotated 90 degrees right saved as penguin_rotated_right.bmp" << std::endl; + + // Test rotate 90 degrees to the left + bmp::Bitmap rotated_left = image.rotate_90_left(); + rotated_left.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_left.bmp"); + std::cout << "Rotated 90 degrees left saved as penguin_rotated_left.bmp" << std::endl; + + return EXIT_SUCCESS; + } + catch (const bmp::Exception& e) { + std::cerr << "Error: " << e.what() << std::endl; + return EXIT_FAILURE; + } +} + diff --git a/images/rotated/penguin_flipped_h.bmp b/images/rotated/penguin_flipped_h.bmp new file mode 100644 index 0000000000000000000000000000000000000000..90bbf7b7c7768a0225583859d3d16a967356da70 GIT binary patch literal 260118 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 F{}1BZ#0mfa literal 0 HcmV?d00001 diff --git a/images/rotated/penguin_rotated_left.bmp b/images/rotated/penguin_rotated_left.bmp new file mode 100644 index 0000000000000000000000000000000000000000..ebecc75a6a92362aa3effa4c464eb5d1143eef4a GIT binary patch literal 259502 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 literal 0 HcmV?d00001 diff --git a/lib/include/BitmapPlusPlus.hpp b/lib/include/BitmapPlusPlus.hpp index fe1336c..fc1b662 100644 --- a/lib/include/BitmapPlusPlus.hpp +++ b/lib/include/BitmapPlusPlus.hpp @@ -466,6 +466,70 @@ namespace bmp { m_pixels[IX(x, y)] = color; } + + /** + * Vertically flips the bitmap and returns the flipped version + * + */ + Bitmap flip_v() { + Bitmap finished(m_width, m_height); + for (std::int32_t x = 0; x < m_width; ++x) { + for (std::int32_t y = 0; y < m_height; ++y) { + // Calculate the reverse y-index + finished.m_pixels[IX(x, y)] = m_pixels[IX(x, m_height - 1 - y)]; + } + } + return finished; + } + + /** + * Horizontally flips the bitmap and returns the flipped version + * + */ + Bitmap flip_h() { + Bitmap finished(m_width, m_height); + for (std::int32_t y = 0; y < m_height; ++y) { + for (std::int32_t x = 0; x < m_width; ++x) { + // Calculate the reverse x-index + finished.m_pixels[IX(x, y)] = m_pixels[IX(m_width - 1 - x, y)]; + } + } + return finished; + } + + /** + * Rotates the bitmap to the right and returns the rotated version + * + */ + Bitmap rotate_90_left() { + Bitmap finished(m_height, m_width); // Swap dimensions + + for (std::int32_t y = 0; y < m_height; ++y) { + std::int32_t y_offset = y * m_width; // Precompute row start index + for (std::int32_t x = 0; x < m_width; ++x) { + // Original pixel at (x, y) moves to (y, m_width - 1 - x) + finished.m_pixels[(m_width - 1 - x) * m_height + y] = m_pixels[y_offset + x]; + } + } + + return finished; + } + + /** + * Rotates the bitmap to the left and returns the rotated version + * + */ + Bitmap rotate_90_right() { + Bitmap finished(m_height, m_width); // Swap dimensions + for (std::int32_t y = 0; y < m_height; ++y) { + std::int32_t y_offset = y * m_width; // Precompute row start index + for (std::int32_t x = 0; x < m_width; ++x) { + finished.m_pixels[x * m_height + (m_height - 1 - y)] = m_pixels[y_offset + x]; + } + } + + return finished; + } /** * Saves Bitmap pixels into a file * @throws bmp::Exception on error @@ -584,7 +648,12 @@ namespace bmp { [[nodiscard]] constexpr std::size_t IX(const std::int32_t x, const std::int32_t y) const noexcept { return static_cast(x) + static_cast(m_width) * static_cast(y); } - + /** + * Converts 2D x,y coords into 1D index, with changed width + */ + [[nodiscard]] constexpr std::size_t IX(const std::int32_t x, const std::int32_t y, const std::int32_t width) const noexcept { + return static_cast(x) + static_cast(m_width) * static_cast(y); + } /** * Returns true if x,y coords are within boundaries */ From d271de10ae99c6a7dd4d65839949e880902355f0 Mon Sep 17 00:00:00 2001 From: Ali Ozer Tekin <74454719+aliozertekin@users.noreply.github.com> Date: Fri, 31 Jan 2025 03:16:59 +0300 Subject: [PATCH 2/2] README.md --- README.md | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index bb1bdda..64bee5c 100644 --- a/README.md +++ b/README.md @@ -249,26 +249,26 @@ int main(void) { bmp::Bitmap image; // Load the original bitmap - image.load("penguin.bmp"); + image.load(std::filesystem::path(ROOT_DIR) / "images" / "penguin.bmp"); // Test vertical flip bmp::Bitmap flipped_v = image.flip_v(); - flipped_v.save("rotated/penguin_flipped_v.bmp"); + flipped_v.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_v.bmp"); std::cout << "Vertical flip saved as penguin_flipped_v.bmp" << std::endl; // Test horizontal flip bmp::Bitmap flipped_h = image.flip_h(); - flipped_h.save("rotated/penguin_flipped_h.bmp"); + flipped_h.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_h.bmp"); std::cout << "Horizontal flip saved as penguin_flipped_h.bmp" << std::endl; // Test rotate 90 degrees to the right bmp::Bitmap rotated_right = image.rotate_90_right(); - rotated_right.save("rotated/penguin_rotated_right.bmp"); + rotated_right.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_right.bmp"); std::cout << "Rotated 90 degrees right saved as penguin_rotated_right.bmp" << std::endl; // Test rotate 90 degrees to the left bmp::Bitmap rotated_left = image.rotate_90_left(); - rotated_left.save("rotated/penguin_rotated_left.bmp"); + rotated_left.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_left.bmp"); std::cout << "Rotated 90 degrees left saved as penguin_rotated_left.bmp" << std::endl; return EXIT_SUCCESS;