156 lines
4.0 KiB
C++
156 lines
4.0 KiB
C++
#include <iostream>
|
|
#include <filesystem>
|
|
#include <algorithm>
|
|
#include <opencv2/highgui.hpp>
|
|
|
|
static constexpr char OUTPUT_DIR[] = "./out";
|
|
|
|
static bool extensionMatches(const std::filesystem::path& path)
|
|
{
|
|
std::string extension = path.extension();
|
|
if(extension == ".png")
|
|
return true;
|
|
if(extension == ".PNG")
|
|
return true;
|
|
if(extension == ".jpg")
|
|
return true;
|
|
if(extension == ".JPG")
|
|
return true;
|
|
if(extension == ".jpeg")
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
int main(int argc, char** argv)
|
|
{
|
|
if(argc < 2)
|
|
{
|
|
std::cout<<"a directory must be specified\n";
|
|
return 1;
|
|
}
|
|
|
|
std::cout<<"Using folder "<<argv[1]<<'\n';
|
|
|
|
std::vector<std::filesystem::path> images;
|
|
const std::filesystem::path directoryPath{argv[1]};
|
|
for(const std::filesystem::directory_entry& dirent : std::filesystem::directory_iterator{directoryPath})
|
|
{
|
|
std::string fileName = dirent.path().filename();
|
|
if(dirent.is_regular_file() && extensionMatches(dirent.path()))
|
|
{
|
|
std::cout<<"Found: "<<dirent.path().filename()<<'\n';
|
|
images.push_back(dirent.path());
|
|
}
|
|
}
|
|
|
|
if(images.empty())
|
|
{
|
|
std::cout<<"No images found\n";
|
|
return 1;
|
|
}
|
|
|
|
std::random_shuffle(images.begin(), images.end());
|
|
|
|
for(const std::filesystem::path& path : images)
|
|
std::cout<<"Found: "<<path.filename()<<'\n';
|
|
|
|
std::filesystem::path outDirPath(OUTPUT_DIR);
|
|
if(!std::filesystem::is_directory(outDirPath) && !std::filesystem::create_directory(outDirPath))
|
|
{
|
|
std::cout<<"Could not create or read "<<OUTPUT_DIR<<'\n';
|
|
return 1;
|
|
}
|
|
|
|
cv::namedWindow("Viewer", cv::WINDOW_NORMAL);
|
|
cv::setWindowTitle("Viewer", "Choose");
|
|
|
|
std::vector<std::vector<std::filesystem::path>> rounds;
|
|
|
|
while(images.size() > 1)
|
|
{
|
|
std::cout<<"New round "<<images.size()<<" images remaining\n";
|
|
rounds.push_back(std::vector<std::filesystem::path>());
|
|
std::vector<size_t> removeIndexies;
|
|
for(size_t i = 0; i < images.size()-1; i+=2)
|
|
{
|
|
cv::Mat imageA = cv::imread(images[i]);
|
|
cv::Mat imageB = cv::imread(images[i+1]);
|
|
|
|
if(!imageA.data || !imageB.data)
|
|
{
|
|
std::cout<<"Images: "<<images[i]<<' '<<images[i+1]<<" failed to read";
|
|
return 1;
|
|
}
|
|
cv::Size2i outSize(imageA.cols+imageB.cols, std::max(imageA.rows, imageB.rows));
|
|
cv::Mat image = cv::Mat::zeros(outSize, imageA.type());
|
|
|
|
cv::Rect roiA(cv::Point(0, 0), imageA.size());
|
|
cv::Rect roiB(cv::Point(imageA.cols, 0), imageB.size());
|
|
imageA.copyTo(image(roiA));
|
|
imageB.copyTo(image(roiB));
|
|
|
|
cv::imshow("Viewer", image);
|
|
while(true)
|
|
{
|
|
int keycode = cv::waitKey(0);
|
|
if(keycode == 49)
|
|
{
|
|
removeIndexies.push_back(i+1);
|
|
break;
|
|
}
|
|
else if(keycode == 50)
|
|
{
|
|
removeIndexies.push_back(i);
|
|
break;
|
|
}
|
|
else if(keycode == 51)
|
|
{
|
|
removeIndexies.push_back(i);
|
|
removeIndexies.push_back(i+1);
|
|
break;
|
|
}
|
|
else if(keycode == 52)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
for(ssize_t i = removeIndexies.size()-1; i >= 0; --i)
|
|
{
|
|
rounds.back().push_back(images[removeIndexies[i]]);
|
|
images.erase(images.begin()+removeIndexies[i]);
|
|
}
|
|
}
|
|
|
|
|
|
for(size_t round = 0; round < rounds.size(); ++round)
|
|
{
|
|
std::string roundDirName = std::string("round_") + std::to_string(round);
|
|
if(!std::filesystem::is_directory(outDirPath/roundDirName) && !std::filesystem::create_directory(outDirPath/roundDirName))
|
|
{
|
|
std::cout<<"Could not create or read "<<outDirPath/roundDirName<<'\n';
|
|
return 1;
|
|
}
|
|
for(const std::filesystem::path& path : rounds[round])
|
|
{
|
|
std::cout<<"Saveing "<<path<<std::endl; //flush
|
|
std::error_code ec;
|
|
std::filesystem::create_hard_link(path, outDirPath/roundDirName/(path.filename()), ec);
|
|
if(ec.value() != 0)
|
|
{
|
|
std::cout<<"Could not create hard link for "<<outDirPath/roundDirName/path.filename()<<'\n';
|
|
}
|
|
}
|
|
}
|
|
|
|
std::error_code ec;
|
|
std::filesystem::path winnerPath(outDirPath/(std::string("winner_") + std::string(images[0].filename())));
|
|
std::filesystem::create_hard_link(images[0], winnerPath, ec);
|
|
if(ec.value() != 0)
|
|
{
|
|
std::cout<<"Could not create hard link for "<<winnerPath<<'\n';
|
|
}
|
|
|
|
return 0;
|
|
}
|