artemis引擎立绘合成工具C++重构版
-
花了点时间用C++写了一遍(
GitHub项目地址:
https://github.com/listder/artemis
源码:#include <bits/stdc++.h> #include <io.h> #include <windows.h> #include <direct.h> #include <opencv2/opencv.hpp> #define image1 img1 #define image2 img2 #define mmax 100000 using namespace cv; using namespace std; void overlayImages(const cv::Mat& background, const cv::Mat& foreground, cv::Mat& output, int x, int y) { output = background.clone(); cv::Rect roi(x, y, foreground.cols, foreground.rows); roi &= cv::Rect(0, 0, background.cols, background.rows); cv::Mat roi_output = output(roi); cv::Mat roi_foreground = foreground(cv::Rect(0, 0, roi.width, roi.height)); for (int i = 0; i < roi.height; ++i) { for (int j = 0; j < roi.width; ++j) { cv::Vec4b pixel_foreground = roi_foreground.at<cv::Vec4b>(i, j); cv::Vec4b& pixel_output = roi_output.at<cv::Vec4b>(i, j); double alpha = pixel_foreground[3] / 255.0; double beta = 1.0 - alpha; for (int k = 0; k < 3; ++k) { pixel_output[k] = static_cast<uchar>(alpha * pixel_foreground[k] + beta * pixel_output[k]); } } } } Mat imagesetmain(Mat img1, Mat img2,int x,int y); void getFileNames(string path, vector<string>& files); void imgset(string path1, string path2); int main(){ system("md output"); system("md input1"); system("md input2"); system("cls"); printf("1.将立绘面部扔在程序目录下的input1文件夹\n2.将立绘底部扔在程序下input2文件夹\n3.然后立绘将生成在output文件夹\n注意事项:请确保文件夹下没有其他类型的文件,并且所有文件为png文件\n"); system("pause"); system("cls"); char cwd[256]; _getcwd(cwd, 256); //cout << cwd << endl; //imgset("G:\\stick\\a0001.png","G:\\stick\\asu_noa0200.png"); string pp = cwd, pp1[mmax], pp2[mmax]; int pn1 = 0, pn2 = 0; vector<string> fileNames1; string path11(pp+"\\input1"); getFileNames(path11, fileNames1); for (const auto &ph1 : fileNames1) { pp1[pn1] = ph1; pn1++; } vector<string> fileNames2; string path22(pp + "\\input2"); getFileNames(path22, fileNames2); for (const auto& ph2 : fileNames2) { pp2[pn2] = ph2; pn2++; } for (int i = 0; i < pn1; i++) for (int j = 0; j < pn2; j++) imgset(pp1[i], pp2[j]); system("cls"); printf("完成!\n"); system("pause"); return 0; } Mat imagesetmain(Mat img1, Mat img2, int x, int y) { /*Mat alpha1, alpha2; extractChannel(img1, alpha1, 3); extractChannel(img2, alpha2, 3); normalize(alpha1, alpha1, 0, 1, NORM_MINMAX, CV_32F); normalize(alpha2, alpha2, 0, 1, NORM_MINMAX, CV_32F); Mat mergedImg = img1.clone(); for (int i = 0; i < img2.rows; ++i) { for (int j = 0; j < img2.cols; ++j) { float alpha = alpha2.at<float>(i, j); for (int c = 0; c < 3; ++c) { mergedImg.at<Vec4b>(y + i, x + j)[c] = static_cast<uchar>((1 - alpha) * mergedImg.at<Vec4b>(y + i, x + j)[c] + alpha * img2.at<Vec4b>(i, j)[c]); } mergedImg.at<Vec4b>(y + i, x + j)[3] = static_cast<uchar>((1 - alpha) * mergedImg.at<Vec4b>(y + i, x + j)[3] + alpha * img2.at<Vec4b>(i, j)[3]); } }*/ Mat mergedImg; overlayImages(img1,img2,mergedImg,x,y); return mergedImg; } void getFileNames(string path, vector<string>& files){ intptr_t hFile = 0; struct _finddata_t fileinfo; string p; if ((hFile = _findfirst(p.assign(path).append("\\*").c_str(), &fileinfo)) != -1){ do{ if ((fileinfo.attrib & _A_SUBDIR)){ if (strcmp(fileinfo.name, ".") != 0 && strcmp(fileinfo.name, "..") != 0) getFileNames(p.assign(path).append("\\").append(fileinfo.name), files); } else{ files.push_back(p.assign(path).append("\\").append(fileinfo.name)); } } while (_findnext(hFile, &fileinfo) == 0); _findclose(hFile); } } void imgset(string path1, string path2){ int x1,y1,x2,y2; ifstream pin1,pin2; pin1.open(path1,ios::in | ios::binary); pin2.open(path2,ios::in | ios::binary); for(char t='a';t!=',';pin1.get(t)) ;//printf("%c", t); //cout<<endl; for(char t='a';t!=',';pin2.get(t)) ;//printf("%c", t); //cout<<endl; pin1>>x1; pin2>>x2; //cout<<x1<<' '<<x2<<endl; pin2.get(); pin1.get(); pin1>>y1; pin2>>y2; //cout<<y1<<' '<<y2<<endl; pin1.close(); pin2.close(); int x=x1-x2,y=y1-y2; Mat img1 = cv::imread(path2, cv::IMREAD_UNCHANGED); Mat img2 = cv::imread(path1, cv::IMREAD_UNCHANGED); Mat mergedImg=imagesetmain(img1, img2, x, y); int plen1 = path1.size(), plen2 = path2.size(), p1=0, p2=0; for (; path1[plen1 - p1] != '\\'; p1++); for (; path2[plen2 - p2] != '\\'; p2++); //cout << p1 << ' ' << p2 << endl; string sp1="", sp2=""; for (int i = 1; i < p1 - 4; i++) sp1 += path1[plen1 - p1 + i]; for (int i = 1; i < p2 - 4; i++) sp2 += path2[plen2 - p2 + i]; //cout << sp1 << ' ' << sp2; imwrite(sp1 + '_' + sp2 + ".png", mergedImg); string temp = "move " + sp1 + '_' + sp2 + ".png" + " output"; system(temp.c_str()); }
编译好的可执行程序:
artemis_win64.7z