18 const std::vector<ports::Rect>& rects,
19 const std::filesystem::path& outputDir,
20 ports::CropRequest::OutputFormat fmt,
22 std::shared_ptr<core::ports::diagnostics::IDiagnostics> debugger,
23 const std::string& filePrefix) {
25 cv::Mat img = cv::imread(imagePath, cv::IMREAD_COLOR);
27 if (debugger && debugger->enabled()) debugger->writeText(
"opencv/error.txt",
"Failed to load image for cropping: " + imagePath);
30 return cropImages(img, rects, outputDir, fmt, jpegQuality,
nullptr, std::move(debugger), filePrefix);
37 const std::vector<ports::Rect>& rects,
38 const std::filesystem::path& outputDir,
39 ports::CropRequest::OutputFormat fmt,
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;
48 if (outBytes) outBytes->clear();
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)));
57 if (!outputDir.empty()) {
59 std::filesystem::create_directories(outputDir, ec);
63 for (
const auto& rct : rects) {
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();
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({});
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);
85 outPaths.emplace_back(filename);
86 if (debugger && debugger->enabled()) {
87 std::ifstream ifs(filename, std::ios::binary);
89 std::vector<uint8_t> buf((std::istreambuf_iterator<char>(ifs)), std::istreambuf_iterator<char>());
90 debugger->writeBytes(std::string(
"opencv_cropped"), buf);
96 if (outBytes) outBytes->push_back({});
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.