Implemented Crop method, and added tests
This commit is contained in:
parent
d5a1e4f93f
commit
2f0d39a797
41
Src/BMP.cpp
41
Src/BMP.cpp
@ -466,6 +466,47 @@ namespace Leonetienne::BmpPP {
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
BMP BMP::Crop(const Eule::Vector2i &topleft, const Eule::Vector2i &cropSize) const {
|
||||
CHECK_IF_INITIALIZED
|
||||
|
||||
// Check that the cropping rect is within our pixel coordinates
|
||||
if (
|
||||
(topleft.x < 0) || (topleft.y < 0) ||
|
||||
(topleft.x + cropSize.x > size.x) || (topleft.y + cropSize.y > size.y)
|
||||
)
|
||||
throw std::runtime_error("Rect coordinates are not contained inside image!");
|
||||
|
||||
// Check that the area of the cropping rect is > 0
|
||||
if (cropSize.x * cropSize.y == 0)
|
||||
throw std::runtime_error("Cropping area is 0!");
|
||||
|
||||
///////////////////
|
||||
// Enough checks...
|
||||
|
||||
// Create a new image of the rects size, and our color mode
|
||||
BMP bmp(cropSize, colormode);
|
||||
|
||||
// Now copy over our pixel data
|
||||
const std::size_t numChannels = GetNumChannels();
|
||||
const std::size_t sourceRowLength = size.x * numChannels;
|
||||
const std::size_t targetRowLength = bmp.GetDimensions().x * numChannels;
|
||||
|
||||
for (std::size_t y = topleft.y; y < topleft.y + cropSize.y; y++) {
|
||||
const std::size_t sourceRowIndex = y * sourceRowLength;
|
||||
const std::size_t targetRowIndex = (y - topleft.y) * targetRowLength;
|
||||
|
||||
// Now just copy over this entire row(segment)
|
||||
std::copy(
|
||||
pixelBuffer.cbegin() + sourceRowIndex + topleft.x * numChannels,
|
||||
pixelBuffer.cbegin() + sourceRowIndex + (topleft.x * numChannels) + targetRowLength,
|
||||
bmp.pixelBuffer.begin() + targetRowIndex
|
||||
);
|
||||
}
|
||||
|
||||
// Done.
|
||||
return bmp;
|
||||
}
|
||||
}
|
||||
|
||||
#undef CHECK_IF_INITIALIZED
|
||||
|
@ -107,7 +107,7 @@ namespace Leonetienne::BmpPP {
|
||||
void SwapChannels(const std::size_t& channel1, const std::size_t& channel2);
|
||||
|
||||
//! Will copy the specified rectangle-area, and return it as a new image
|
||||
BMP Crop(const Eule::Rect& area) const;
|
||||
BMP Crop(const Eule::Vector2i& topleft, const Eule::Vector2i& size) const;
|
||||
|
||||
//! Will fill a specific channel with a value
|
||||
void FillChannel(const std::size_t& channel, const std::uint8_t value);
|
||||
|
@ -30,6 +30,7 @@ add_executable(Test
|
||||
SwapChannels.cpp
|
||||
Rotate.cpp
|
||||
ConvertColormode.cpp
|
||||
Crop.cpp
|
||||
)
|
||||
|
||||
# Move test images to build dir
|
||||
|
100
Test/Crop.cpp
Normal file
100
Test/Crop.cpp
Normal file
@ -0,0 +1,100 @@
|
||||
#include <Bmp.h>
|
||||
#include <stdexcept>
|
||||
#include "Catch2.h"
|
||||
|
||||
using namespace Leonetienne::BmpPP;
|
||||
using namespace Eule;
|
||||
|
||||
// Tests that cropping produces the correct result
|
||||
TEST_CASE(__FILE__"/HappyPath", "[Cropping]")
|
||||
{
|
||||
SECTION("RGB") {
|
||||
// Read an image
|
||||
BMP bmp("base_hachi.bmp");
|
||||
|
||||
// Crop it
|
||||
bmp = bmp.Crop(
|
||||
Vector2i(95, 83),
|
||||
Vector2i(149, 239)
|
||||
);
|
||||
|
||||
// Read reference image
|
||||
const BMP reference("base_hachi_cropped.bmp");
|
||||
|
||||
// Assert that they are equal
|
||||
REQUIRE(bmp == reference);
|
||||
}
|
||||
|
||||
SECTION("RGBA") {
|
||||
// Read an image
|
||||
BMP bmp("basea_hachi.bmp");
|
||||
|
||||
// Crop it
|
||||
bmp = bmp.Crop(
|
||||
Vector2i(95, 83),
|
||||
Vector2i(149, 239)
|
||||
);
|
||||
|
||||
// Read reference image
|
||||
const BMP reference("basea_hachi_cropped.bmp");
|
||||
|
||||
// Assert that they are equal
|
||||
REQUIRE(bmp == reference);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// Tests that cropping with extreme points works (like, 0,0, widht, height)
|
||||
TEST_CASE(__FILE__"/ExtremePoints", "[Cropping]")
|
||||
{
|
||||
SECTION("Crop includes {0,0}") {
|
||||
// Read an image
|
||||
BMP bmp("base_hachi.bmp");
|
||||
|
||||
// Crop it
|
||||
bmp = bmp.Crop(
|
||||
Vector2i(0, 0),
|
||||
Vector2i(252, 337)
|
||||
);
|
||||
|
||||
// Read reference image
|
||||
const BMP reference("base_hachi_cropped_extreme_topleft.bmp");
|
||||
|
||||
// Assert that they are equal
|
||||
REQUIRE(bmp == reference);
|
||||
}
|
||||
|
||||
SECTION("Crop includes {width, height}") {
|
||||
// Read an image
|
||||
BMP bmp("base_hachi.bmp");
|
||||
|
||||
// Crop it
|
||||
bmp = bmp.Crop(
|
||||
Vector2i(96, 54),
|
||||
bmp.GetDimensions() - Vector2i(96, 54) // As far-right as we can get
|
||||
);
|
||||
|
||||
// Read reference image
|
||||
const BMP reference("base_hachi_cropped_extreme_bottomright.bmp");
|
||||
|
||||
// Assert that they are equal
|
||||
REQUIRE(bmp == reference);
|
||||
}
|
||||
|
||||
SECTION("Crop includes {0, 0, width, height}") {
|
||||
// Read an image
|
||||
BMP bmp("base_hachi.bmp");
|
||||
|
||||
// Crop it (without taking away anything, lol)
|
||||
BMP cropped = bmp.Crop(
|
||||
Vector2i(0, 0),
|
||||
bmp.GetDimensions() // As far-right as we can get
|
||||
);
|
||||
|
||||
// Assert that the cropped image remains the same (as we cropped from 0,0 to width,height)
|
||||
REQUIRE(bmp == cropped);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
BIN
Test/TestAssets/base_hachi.bmp
Normal file
BIN
Test/TestAssets/base_hachi.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 624 KiB |
BIN
Test/TestAssets/base_hachi_cropped.bmp
Normal file
BIN
Test/TestAssets/base_hachi_cropped.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 105 KiB |
BIN
Test/TestAssets/base_hachi_cropped_extreme_bottomright.bmp
Normal file
BIN
Test/TestAssets/base_hachi_cropped_extreme_bottomright.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 430 KiB |
BIN
Test/TestAssets/base_hachi_cropped_extreme_topleft.bmp
Normal file
BIN
Test/TestAssets/base_hachi_cropped_extreme_topleft.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 249 KiB |
BIN
Test/TestAssets/basea_hachi.bmp
Normal file
BIN
Test/TestAssets/basea_hachi.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 830 KiB |
BIN
Test/TestAssets/basea_hachi_cropped.bmp
Normal file
BIN
Test/TestAssets/basea_hachi_cropped.bmp
Normal file
Binary file not shown.
After Width: | Height: | Size: 139 KiB |
Loading…
x
Reference in New Issue
Block a user