FOSSredder 0.5.0
Loading...
Searching...
No Matches
CropAdapter.cpp
Go to the documentation of this file.
1
5
9#include <opencv2/opencv.hpp>
10#include <filesystem>
11#include <fstream>
12#include <sstream>
13
14namespace opencv {
15namespace ports = core::ports::document_image_processing;
16
17std::vector<std::filesystem::path> CropAdapter::cropImages(const std::string& imagePath,
18 const std::vector<ports::Rect>& rects,
19 const std::filesystem::path& outputDir,
20 ports::CropRequest::OutputFormat fmt,
21 int jpegQuality,
22 std::shared_ptr<core::ports::diagnostics::IDiagnostics> debugger,
23 const std::string& filePrefix) {
24 try {
25 cv::Mat img = cv::imread(imagePath, cv::IMREAD_COLOR);
26 if (img.empty()) {
27 if (debugger && debugger->enabled()) debugger->writeText("opencv/error.txt", "Failed to load image for cropping: " + imagePath);
28 return {};
29 }
30 return cropImages(img, rects, outputDir, fmt, jpegQuality, nullptr, std::move(debugger), filePrefix);
31 } catch (...) {
32 return {};
33 }
34}
35
36std::vector<std::filesystem::path> CropAdapter::cropImages(const cv::Mat& img,
37 const std::vector<ports::Rect>& rects,
38 const std::filesystem::path& outputDir,
39 ports::CropRequest::OutputFormat fmt,
40 int jpegQuality,
41 std::vector<std::vector<uint8_t>>* outBytes,
42 std::shared_ptr<core::ports::diagnostics::IDiagnostics> debugger,
43 const std::string& filePrefix) {
44 std::vector<std::filesystem::path> outPaths;
45 if (rects.empty()) return outPaths;
46 if (img.empty()) return outPaths;
47
48 if (outBytes) outBytes->clear();
49
50 const char* ext = (fmt == ports::CropRequest::OutputFormat::Jpg) ? ".jpg" : ".png";
51 std::vector<int> encodeParams;
52 if (fmt == ports::CropRequest::OutputFormat::Jpg) {
53 encodeParams.push_back(cv::IMWRITE_JPEG_QUALITY);
54 encodeParams.push_back(std::max(1, std::min(100, jpegQuality)));
55 }
56
57 if (!outputDir.empty()) {
58 std::error_code ec;
59 std::filesystem::create_directories(outputDir, ec);
60 }
61
62 int idx = 0;
63 for (const auto& rct : rects) {
64 try {
65 cv::Rect r(rct.x, rct.y, rct.width, rct.height);
66 r &= cv::Rect(0, 0, img.cols, img.rows);
67 if (r.width <= 0 || r.height <= 0) { ++idx; continue; }
68 cv::Mat crop = img(r).clone();
69
70 if (outBytes) {
71 std::vector<uint8_t> buf;
72 if (cv::imencode(ext, crop, buf, encodeParams)) outBytes->push_back(std::move(buf));
73 else outBytes->push_back({});
74 }
75
76 if (!outputDir.empty()) {
77 std::ostringstream fname;
78 fname << (outputDir.string()) << "/";
79 if (!filePrefix.empty()) fname << filePrefix << "_";
80 fname << (idx + 1) << ext;
81 std::string filename = fname.str();
82 if (!cv::imwrite(filename, crop, encodeParams)) {
83 if (debugger && debugger->enabled()) debugger->writeText("opencv/error.txt", "Failed to write crop: " + filename);
84 } else {
85 outPaths.emplace_back(filename);
86 if (debugger && debugger->enabled()) {
87 std::ifstream ifs(filename, std::ios::binary);
88 if (ifs) {
89 std::vector<uint8_t> buf((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
90 debugger->writeBytes(std::string("opencv_cropped"), buf);
91 }
92 }
93 }
94 }
95 } catch (...) {
96 if (outBytes) outBytes->push_back({});
97 }
98 ++idx;
99 }
100
101 return outPaths;
102}
103
104} // namespace opencv
Declares the OpenCV crop adapter used by the import workflow.
Declares the diagnostics artifact writing port.
static std::vector< std::filesystem::path > cropImages(const std::string &imagePath, const std::vector< ports::Rect > &rects, const std::filesystem::path &outputDir, ports::CropRequest::OutputFormat fmt, int jpegQuality=92, std::shared_ptr< core::ports::diagnostics::IDiagnostics > debugger=nullptr, const std::string &filePrefix="")
Crops multiple rectangles from an image file and writes the results to disk.
Precompiled header for the document-image-processing infrastructure module.