Skip to content

Commit 0853118

Browse files
authored
Merge pull request #4 from aliozertekin/contribute
Bitmap rotation handling
2 parents 3ce22ef + d271de1 commit 0853118

File tree

7 files changed

+159
-1
lines changed

7 files changed

+159
-1
lines changed

README.md

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,57 @@ int main(void) {
236236
![modified-penguin](images/modified-penguin.bmp)
237237
238238
239+
<br><br>
240+
<strong>Rotate, Flip The Penguin</strong>
241+
<br>
242+
243+
```cpp
244+
#include "BitmapPlusPlus.hpp"
245+
#include <iostream>
246+
247+
int main(void) {
248+
try {
249+
bmp::Bitmap image;
250+
251+
// Load the original bitmap
252+
image.load(std::filesystem::path(ROOT_DIR) / "images" / "penguin.bmp");
253+
254+
// Test vertical flip
255+
bmp::Bitmap flipped_v = image.flip_v();
256+
flipped_v.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_v.bmp");
257+
std::cout << "Vertical flip saved as penguin_flipped_v.bmp" << std::endl;
258+
259+
// Test horizontal flip
260+
bmp::Bitmap flipped_h = image.flip_h();
261+
flipped_h.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_h.bmp");
262+
std::cout << "Horizontal flip saved as penguin_flipped_h.bmp" << std::endl;
263+
264+
// Test rotate 90 degrees to the right
265+
bmp::Bitmap rotated_right = image.rotate_90_right();
266+
rotated_right.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_right.bmp");
267+
std::cout << "Rotated 90 degrees right saved as penguin_rotated_right.bmp" << std::endl;
268+
269+
// Test rotate 90 degrees to the left
270+
bmp::Bitmap rotated_left = image.rotate_90_left();
271+
rotated_left.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_left.bmp");
272+
std::cout << "Rotated 90 degrees left saved as penguin_rotated_left.bmp" << std::endl;
273+
274+
return EXIT_SUCCESS;
275+
}
276+
catch (const bmp::Exception& e) {
277+
std::cerr << "Error: " << e.what() << std::endl;
278+
return EXIT_FAILURE;
279+
}
280+
}
281+
282+
```
283+
![penguin](images/penguin.bmp)
284+
![penguin_flipped_v](images/rotated/penguin_flipped_v.bmp)
285+
![penguin_flipped_h](images/rotated/penguin_flipped_h.bmp)
286+
![penguin_rotated_right](images/rotated/penguin_rotated_right.bmp)
287+
![penguin_rotated_left](images/rotated/penguin_rotated_left.bmp)
288+
289+
239290
<br><br>
240291

241292
<strong>Chess Board</strong>

examples/rotation.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#include "BitmapPlusPlus.hpp"
2+
#include <iostream>
3+
4+
int main(void) {
5+
try {
6+
bmp::Bitmap image;
7+
8+
// Load the original bitmap
9+
image.load(std::filesystem::path(ROOT_DIR) / "images" / "penguin.bmp");
10+
11+
// Test vertical flip
12+
bmp::Bitmap flipped_v = image.flip_v();
13+
flipped_v.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_v.bmp");
14+
std::cout << "Vertical flip saved as penguin_flipped_v.bmp" << std::endl;
15+
16+
// Test horizontal flip
17+
bmp::Bitmap flipped_h = image.flip_h();
18+
flipped_h.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_flipped_h.bmp");
19+
std::cout << "Horizontal flip saved as penguin_flipped_h.bmp" << std::endl;
20+
21+
// Test rotate 90 degrees to the right
22+
bmp::Bitmap rotated_right = image.rotate_90_right();
23+
rotated_right.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_right.bmp");
24+
std::cout << "Rotated 90 degrees right saved as penguin_rotated_right.bmp" << std::endl;
25+
26+
// Test rotate 90 degrees to the left
27+
bmp::Bitmap rotated_left = image.rotate_90_left();
28+
rotated_left.save(std::filesystem::path(ROOT_DIR) / "images" / "rotated" / "penguin_rotated_left.bmp");
29+
std::cout << "Rotated 90 degrees left saved as penguin_rotated_left.bmp" << std::endl;
30+
31+
return EXIT_SUCCESS;
32+
}
33+
catch (const bmp::Exception& e) {
34+
std::cerr << "Error: " << e.what() << std::endl;
35+
return EXIT_FAILURE;
36+
}
37+
}
38+

images/rotated/penguin_flipped_h.bmp

254 KB
Binary file not shown.

images/rotated/penguin_flipped_v.bmp

254 KB
Binary file not shown.
253 KB
Binary file not shown.
253 KB
Binary file not shown.

lib/include/BitmapPlusPlus.hpp

Lines changed: 70 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,6 +466,70 @@ namespace bmp {
466466
m_pixels[IX(x, y)] = color;
467467
}
468468

469+
470+
/**
471+
* Vertically flips the bitmap and returns the flipped version
472+
*
473+
*/
474+
Bitmap flip_v() {
475+
Bitmap finished(m_width, m_height);
476+
for (std::int32_t x = 0; x < m_width; ++x) {
477+
for (std::int32_t y = 0; y < m_height; ++y) {
478+
// Calculate the reverse y-index
479+
finished.m_pixels[IX(x, y)] = m_pixels[IX(x, m_height - 1 - y)];
480+
}
481+
}
482+
return finished;
483+
}
484+
485+
/**
486+
* Horizontally flips the bitmap and returns the flipped version
487+
*
488+
*/
489+
Bitmap flip_h() {
490+
Bitmap finished(m_width, m_height);
491+
for (std::int32_t y = 0; y < m_height; ++y) {
492+
for (std::int32_t x = 0; x < m_width; ++x) {
493+
// Calculate the reverse x-index
494+
finished.m_pixels[IX(x, y)] = m_pixels[IX(m_width - 1 - x, y)];
495+
}
496+
}
497+
return finished;
498+
}
499+
500+
/**
501+
* Rotates the bitmap to the right and returns the rotated version
502+
*
503+
*/
504+
Bitmap rotate_90_left() {
505+
Bitmap finished(m_height, m_width); // Swap dimensions
506+
507+
for (std::int32_t y = 0; y < m_height; ++y) {
508+
std::int32_t y_offset = y * m_width; // Precompute row start index
509+
for (std::int32_t x = 0; x < m_width; ++x) {
510+
// Original pixel at (x, y) moves to (y, m_width - 1 - x)
511+
finished.m_pixels[(m_width - 1 - x) * m_height + y] = m_pixels[y_offset + x];
512+
}
513+
}
514+
515+
return finished;
516+
}
517+
518+
/**
519+
* Rotates the bitmap to the left and returns the rotated version
520+
*
521+
*/
522+
Bitmap rotate_90_right() {
523+
Bitmap finished(m_height, m_width); // Swap dimensions
524+
for (std::int32_t y = 0; y < m_height; ++y) {
525+
std::int32_t y_offset = y * m_width; // Precompute row start index
526+
for (std::int32_t x = 0; x < m_width; ++x) {
527+
finished.m_pixels[x * m_height + (m_height - 1 - y)] = m_pixels[y_offset + x];
528+
}
529+
}
530+
531+
return finished;
532+
}
469533
/**
470534
* Saves Bitmap pixels into a file
471535
* @throws bmp::Exception on error
@@ -584,7 +648,12 @@ namespace bmp {
584648
[[nodiscard]] constexpr std::size_t IX(const std::int32_t x, const std::int32_t y) const noexcept {
585649
return static_cast<std::size_t>(x) + static_cast<std::size_t>(m_width) * static_cast<std::size_t>(y);
586650
}
587-
651+
/**
652+
* Converts 2D x,y coords into 1D index, with changed width
653+
*/
654+
[[nodiscard]] constexpr std::size_t IX(const std::int32_t x, const std::int32_t y, const std::int32_t width) const noexcept {
655+
return static_cast<std::size_t>(x) + static_cast<std::size_t>(m_width) * static_cast<std::size_t>(y);
656+
}
588657
/**
589658
* Returns true if x,y coords are within boundaries
590659
*/

0 commit comments

Comments
 (0)