diff options
author | Stanislaw Halik <sthalik@misaki.pl> | 2022-09-30 18:55:15 +0200 |
---|---|---|
committer | Stanislaw Halik <sthalik@misaki.pl> | 2022-09-30 18:55:15 +0200 |
commit | 5ee36284ab2f2d85679f83ad7680a741bf7f6702 (patch) | |
tree | 825566e0a21b6b7b8d0ad3f81880ebe4c3f3ce3d /anim-crop-tool | |
parent | c7ce9f57f53325e47574bf0fcdaa495146656289 (diff) |
.
Diffstat (limited to 'anim-crop-tool')
-rw-r--r-- | anim-crop-tool/CMakeLists.txt | 10 | ||||
-rw-r--r-- | anim-crop-tool/atlas.cpp | 63 | ||||
-rw-r--r-- | anim-crop-tool/atlas.hpp | 37 |
3 files changed, 110 insertions, 0 deletions
diff --git a/anim-crop-tool/CMakeLists.txt b/anim-crop-tool/CMakeLists.txt new file mode 100644 index 00000000..7b6d22a8 --- /dev/null +++ b/anim-crop-tool/CMakeLists.txt @@ -0,0 +1,10 @@ +find_package(OpenCV QUIET REQUIRED COMPONENTS core imgcodecs imgproc) +set(self "${PROJECT_NAME}-anim-crop-tool") + +include_directories(SYSTEM PRIVATE ${OpenCV_INCLUDE_DIRS}) +link_libraries(Corrade::Utility) +link_libraries(${PROJECT_NAME}-anim) + +file(GLOB sources "*.cpp" CONFIGURE_ARGS) +add_executable(${self} ${sources}) +install(TARGETS ${self} RUNTIME DESTINATION "bin") diff --git a/anim-crop-tool/atlas.cpp b/anim-crop-tool/atlas.cpp new file mode 100644 index 00000000..a588ff3c --- /dev/null +++ b/anim-crop-tool/atlas.cpp @@ -0,0 +1,63 @@ +#undef NDEBUG + +#include "atlas.hpp" +#include "anim/serialize.hpp" + +#include <cassert> +#include <filesystem> +#include <opencv2/imgcodecs.hpp> + +void anim_atlas_row::add_entry(const anim_atlas_entry& x) noexcept +{ + auto& frame = *x.frame; + const auto& mat = x.mat; + frame.offset = {xpos, ypos}; + frame.size = {mat.cols, mat.rows}; + + assert(mat.rows > 0 && mat.cols > 0); + data.push_back(x); + xpos += mat.cols; + max_height = std::max(mat.rows, max_height); +} + +void anim_atlas::advance_row() noexcept +{ + auto& row = rows.back(); + if (row.data.empty()) + return; + assert(row.xpos); assert(row.max_height); + ypos += row.max_height; + maxx = std::max(row.xpos, maxx); + rows.push_back({{}, 0, 0, ypos}); +} + +Magnum::Vector2i anim_atlas::offset() const noexcept +{ + const auto& row = rows.back(); + return {row.xpos, row.ypos}; +} + +Magnum::Vector2i anim_atlas::size() const noexcept +{ + const anim_atlas_row& row = rows.back(); + // prevent accidentally writing out of bounds by forgetting to call + // anim_atlas::advance_row() one last time prior to anim_atlas::size() + return {std::max(maxx, row.xpos), ypos + row.max_height}; +} + +bool anim_atlas::dump(const std::filesystem::path& filename) const noexcept +{ + auto sz = size(); + cv::Mat4b mat(sz[1], sz[0]); + mat.setTo(0); + + for (const anim_atlas_row& row : rows) + for (const anim_atlas_entry& x : row.data) + { + auto offset = x.frame->offset, size = x.frame->size; + cv::Rect roi = {offset[0], offset[1], size[0], size[1]}; + x.mat.copyTo(mat(roi)); + } + + return cv::imwrite(filename.string(), mat); +} diff --git a/anim-crop-tool/atlas.hpp b/anim-crop-tool/atlas.hpp new file mode 100644 index 00000000..5c5e918f --- /dev/null +++ b/anim-crop-tool/atlas.hpp @@ -0,0 +1,37 @@ +#pragma once + +#include <vector> +#include <Magnum/Magnum.h> +#include <Magnum/Math/Vector2.h> +#include <opencv2/core/mat.hpp> + +struct anim_frame; + +namespace std::filesystem { class path; } + +struct anim_atlas_entry +{ + anim_frame* frame; + cv::Mat4b mat; +}; + +struct anim_atlas_row +{ + std::vector<anim_atlas_entry> data; + int max_height = 0, xpos = 0, ypos = 0; + + void add_entry(const anim_atlas_entry& x) noexcept; +}; + +class anim_atlas +{ + std::vector<anim_atlas_row> rows = {{}}; + int ypos = 0, maxx = 0; + +public: + void add_entry(const anim_atlas_entry& x) noexcept { rows.back().add_entry(x); } + void advance_row() noexcept; + Magnum::Vector2i offset() const noexcept; + Magnum::Vector2i size() const noexcept; + [[nodiscard]] bool dump(const std::filesystem::path& filename) const noexcept; +}; |