Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include "Source.h"
- #define FIRST_PATH_BUTTON_ID 1001
- #define SECOND_PATH_BUTTON_ID 1002
- #define FIND_DUPLICATES_BUTTON_ID 1003
- #define EXTENSION_CHECKBOX_ID 1004
- #define MAX_LOADSTRING 100
- #define FONT_SIZE 12
- #define MAX_PATH_LENGTH 60
- HINSTANCE hInst;
- WCHAR title[MAX_LOADSTRING] = L"OSaSP2";
- WCHAR windowClass[MAX_LOADSTRING] = L"OSaSP2Class";
- wstring firstSelectedPath;
- wstring secondSelectedPath;
- wstring reducedFirstPath;
- wstring reducedSecondPath;
- const int buttonWidth = 130;
- const int buttonHeight = 30;
- const int xMargin = 15;
- const int yMargin = 10;
- vector<vector<filesystem::path>*>* images = new vector<vector<filesystem::path>*>;
- const set<string> extensions{ ".jpg", ".png", ".bmp", ".tiff", ".jpeg", ".icon", ".gif", ".exif", ".wmf", ".emf" };
- RECT rect;
- OPENFILENAME ofn;
- WCHAR fileName[MAX_PATH];
- ATOM MyRegisterClass(HINSTANCE hInstance);
- BOOL InitInstance(HINSTANCE, int);
- LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
- void pathClick(HWND hWnd, wstring& path, wstring& reducedPath);
- LPWSTR getPath(HWND hwnd);
- wstring reducePath(wstring path);
- void saveToFile();
- bool check_extension(const filesystem::path& file);
- string to_lower(string str);
- void get_files(const filesystem::path& path, vector<vector<filesystem::path>*>* files);
- bool compare_files(const filesystem::path file1, filesystem::path file2);
- void find_duplicates(vector<vector<filesystem::path>*>* files);
- Image* get_gray_scale_version(Image* image);
- Image* resize(Image* image);
- void array_destroyer(::byte** ary, unsigned int dim1);
- ::byte** array_generator(unsigned int dim1, unsigned int dim2);
- FLOAT start_comparing(Image* firstImage, Image* secondImage, ::byte threshold);
- int CALLBACK wWinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPWSTR lpCmdLine, int nCmdShow)
- {
- GdiplusStartupInput gdiplusStartupInput;
- ULONG_PTR gdiplusToken;
- GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);
- MyRegisterClass(hInstance);
- if (!InitInstance(hInstance, nCmdShow))
- {
- return FALSE;
- }
- MSG msg;
- while (GetMessage(&msg, nullptr, 0, 0))
- {
- TranslateMessage(&msg);
- DispatchMessage(&msg);
- }
- GdiplusShutdown(gdiplusToken);
- return (int)msg.wParam;
- }
- ATOM MyRegisterClass(HINSTANCE hInstance)
- {
- WNDCLASSEX wcex;
- wcex.cbSize = sizeof(WNDCLASSEX);
- wcex.cbClsExtra = 0;
- wcex.cbWndExtra = 0;
- wcex.style = CS_HREDRAW | CS_VREDRAW;
- wcex.lpfnWndProc = WndProc;
- wcex.hInstance = hInstance;
- wcex.hIcon = LoadIcon(nullptr, IDI_APPLICATION);
- wcex.hIconSm = LoadIcon(nullptr, IDI_APPLICATION);
- wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
- wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW + 1);
- wcex.lpszMenuName = nullptr;
- wcex.lpszClassName = windowClass;
- return RegisterClassEx(&wcex);
- }
- BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
- {
- hInst = hInstance;
- HWND hWnd = CreateWindowW(windowClass, title, WS_OVERLAPPEDWINDOW,
- CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
- if (!hWnd)
- return FALSE;
- ShowWindow(hWnd, nCmdShow);
- UpdateWindow(hWnd);
- return TRUE;
- }
- void saveToFile()
- {
- std::ofstream fout("C:\\Users\\evgeny\\Desktop\\123.txt");
- int i = 0;
- fout << "Duplicates" << endl << endl;
- for (auto iter1 = images->begin(); iter1 != images->end(); ++iter1)
- {
- if ((*iter1)->size() < 2)
- {
- continue;
- }
- fout << ++i << ":" << endl;
- for (auto iter2 = (*iter1)->begin(); iter2 != (*iter1)->end(); ++iter2)
- {
- fout << (*iter2).string() << endl;
- }
- fout << endl;
- fout << endl;
- }
- fout.close();
- }
- LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
- {
- static HWND firstImgButton;
- static HWND secondImgButton;
- static HWND calculateButton;
- static HWND extensionCheckbox;
- Font font(L"Arial", FONT_SIZE, FontStyleBold);
- GetClientRect(hWnd, &rect);
- switch (message)
- {
- case WM_COMMAND:
- {
- int wmId = LOWORD(wParam);
- switch (wmId)
- {
- case FIRST_PATH_BUTTON_ID:
- pathClick(hWnd, firstSelectedPath, reducedFirstPath);
- break;
- case SECOND_PATH_BUTTON_ID:
- pathClick(hWnd, secondSelectedPath, reducedSecondPath);
- break;
- case FIND_DUPLICATES_BUTTON_ID:
- delete images;
- images = new vector<vector<filesystem::path>*>;
- get_files(firstSelectedPath, images);
- get_files(secondSelectedPath, images);
- find_duplicates(images);
- saveToFile();
- break;
- case EXTENSION_CHECKBOX_ID:
- {
- BOOL checked = IsDlgButtonChecked(hWnd, EXTENSION_CHECKBOX_ID);
- if (checked) {
- CheckDlgButton(hWnd, EXTENSION_CHECKBOX_ID, BST_UNCHECKED);
- }
- else {
- CheckDlgButton(hWnd, EXTENSION_CHECKBOX_ID, BST_CHECKED);
- }
- }
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- }
- break;
- case WM_PAINT:
- {
- PAINTSTRUCT ps;
- SolidBrush brush(Color::Black);
- HDC hdc = BeginPaint(hWnd, &ps);
- if(!reducedFirstPath.empty())
- {
- Graphics graphics(hdc);
- PointF origin(xMargin * 2 + buttonWidth, yMargin + FONT_SIZE / 2);
- graphics.DrawString(reducedFirstPath.c_str(), reducedFirstPath.length(), &font, origin, &brush);
- }
- if (!reducedSecondPath.empty())
- {
- Graphics graphics(hdc);
- PointF origin(xMargin * 2 + buttonWidth, yMargin * 2 + buttonHeight + FONT_SIZE / 2);
- graphics.DrawString(reducedSecondPath.c_str(), reducedSecondPath.length(), &font, origin, &brush);
- }
- EndPaint(hWnd, &ps);
- }
- case WM_KEYDOWN:
- switch (wParam)
- {
- case VK_F1:
- break;
- }
- break;
- case WM_CREATE:
- if (GetWindowRect(hWnd, &rect))
- {
- int width = rect.right - rect.left;
- int height = rect.bottom - rect.top;
- firstImgButton = CreateWindow(L"button", L"Get first path",
- WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
- xMargin, yMargin,
- buttonWidth, buttonHeight,
- hWnd, (HMENU)FIRST_PATH_BUTTON_ID,
- hInst, NULL);
- secondImgButton = CreateWindow(L"button", L"Get second path",
- WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
- xMargin, buttonHeight + yMargin * 2,
- buttonWidth, buttonHeight,
- hWnd, (HMENU)SECOND_PATH_BUTTON_ID,
- hInst, NULL);
- extensionCheckbox = CreateWindow(L"button", L"Check extension",
- WS_CHILD | WS_VISIBLE | BS_CHECKBOX,
- xMargin, buttonHeight * 2 + yMargin * 3,
- buttonWidth, buttonHeight,
- hWnd, (HMENU)EXTENSION_CHECKBOX_ID,
- hInst, NULL);
- calculateButton = CreateWindow(L"button", L"Find duplicates",
- WS_CHILD | WS_VISIBLE | BS_DEFPUSHBUTTON,
- xMargin, buttonHeight * 3 + yMargin * 4,
- buttonWidth, buttonHeight,
- hWnd, (HMENU)FIND_DUPLICATES_BUTTON_ID,
- hInst, NULL);
- }
- break;
- case WM_DESTROY:
- PostQuitMessage(0);
- break;
- default:
- return DefWindowProc(hWnd, message, wParam, lParam);
- }
- return 0;
- }
- void pathClick(HWND hWnd, wstring& path, wstring& reducedPath)
- {
- const LPWSTR selectedPath = getPath(hWnd);
- if (selectedPath != nullptr)
- {
- path = selectedPath;
- reducedPath = reducePath(selectedPath);
- }
- InvalidateRect(hWnd, 0, TRUE);
- }
- LPWSTR getPath(HWND hWnd)
- {
- LPWSTR file = new WCHAR[1024];
- ZeroMemory(&ofn, sizeof(ofn));
- ofn.lStructSize = sizeof(ofn);
- ofn.hwndOwner = nullptr;
- file[0] = '\0';
- ofn.lpstrFile = file;
- ofn.nMaxFile = 1024;
- ofn.lpstrFilter = L"Pictures (*.ICON;*.png; *.GIF; *.JPEG; *.Exif; *.PNG; *.TIFF; *.WMF; *.EMF; *.BMP; *.JPG)\0*.ICON;*.png; *.GIF; *.JPEG; *.Exif; *.PNG; *.TIFF; *.WMF; *.EMF; *.BMP; *.JPG\0All Files (*.*)\0*.*\0";
- ofn.Flags = OFN_ALLOWMULTISELECT | OFN_EXPLORER | OFN_PATHMUSTEXIST | OFN_FILEMUSTEXIST | OFN_NOVALIDATE;
- if (GetOpenFileName(&ofn))
- return ofn.lpstrFile;
- //MessageBoxA(hWnd, "Can't open file", "Caption", NULL);
- return nullptr;
- }
- wstring reducePath(wstring path)
- {
- if(path.length() > MAX_PATH_LENGTH)
- {
- const wstring file(path.begin() + path.find_last_of(L'\\') + 1, path.end());
- if(file.length() > MAX_PATH_LENGTH - 4)
- {
- return file.substr(0, MAX_PATH_LENGTH / 2 - 3).append(L"...")
- .append(file.substr(file.length() - MAX_PATH_LENGTH / 2 + 3, file.length()));
- }
- return path.substr(0, MAX_PATH_LENGTH - 4 - file.length()).append(L"...\\").append(file);
- }
- return path;
- }
- string to_lower(string str)
- {
- std::transform(str.begin(), str.end(), str.begin(), [](unsigned char c)
- { return std::tolower(c); });
- return str;
- }
- bool check_extension(const filesystem::path& file)
- {
- const string extension = to_lower(file.extension().string());
- return extensions.count(extension);
- }
- void get_files(const filesystem::path& path, vector<vector<filesystem::path>*>* files)
- {
- if (!is_directory(path))
- {
- files->push_back(new vector<filesystem::path>);
- files->back()->push_back(path);
- }
- else
- {
- for (const auto& p : std::filesystem::recursive_directory_iterator(path))
- {
- if (!is_directory(p) && check_extension(p.path()))
- {
- files->push_back(new vector<filesystem::path>);
- files->back()->push_back(p.path());
- }
- }
- }
- }
- bool compare_files(const filesystem::path file1, const filesystem::path file2)
- {
- if (file1.extension() == file2.extension() && file_size(file1) == file_size(file2))
- {
- return start_comparing(new Image(file1.c_str()), new Image(file2.c_str()), 4) == 0;
- }
- return false;
- }
- void find_duplicates(vector<vector<filesystem::path>*>* files)
- {
- for (auto i = 0; i < files->size(); i++)
- {
- for (auto iterator = files->begin() + i + 1; iterator != files->end(); ++iterator)
- {
- if (compare_files(files->at(i)->front(), (*iterator)->front()))
- {
- files->at(i)->push_back((*iterator)->front());
- iterator = files->erase(iterator);
- --iterator;
- }
- }
- }
- }
- FLOAT start_comparing(Image* firstImage, Image* secondImage, ::byte threshold)
- {
- Image* smallImage1 = resize(firstImage);
- Image* smallImage2 = resize(secondImage);
- Bitmap* thisOne = (Bitmap*)(get_gray_scale_version(resize(get_gray_scale_version(smallImage1))));
- Bitmap* theOtherOne = (Bitmap*)get_gray_scale_version(resize(get_gray_scale_version(smallImage2)));
- int size = 16;
- ::byte** differences = array_generator(size, size);
- ::byte** firstGrayScale = array_generator(size, size);//new ::byte[size, size];
- ::byte** secondGrayScale = array_generator(size, size); //new ::byte[size, size];
- Color pixelColor;
- for (int x = 0; x < 16; x++)
- {
- for (int y = 0; y < 16; y++)
- {
- thisOne->GetPixel(x, y, &pixelColor);
- //int j = 8;
- firstGrayScale[x][y] = (::byte)abs(pixelColor.GetRed());
- //firstGrayScale[x][y] = resultPixels[x][y];
- }
- }
- for (int x = 0; x < 16; x++)
- {
- for (int y = 0; y < 16; y++)
- {
- //Color pixelColor;
- theOtherOne->GetPixel(x, y, &pixelColor);
- secondGrayScale[x][y] = abs(pixelColor.GetRed());
- //secondGrayScale[x][y] = resultPixels1[x][y];
- }
- }
- for (int x = 0; x < 16; x++)
- {
- for (int y = 0; y < 16; y++)
- {
- differences[x][y] = (::byte)abs(firstGrayScale[x][y] - secondGrayScale[x][y]);
- }
- }
- int diffPixels = 0;
- for (int i = 0; i < 16; i++)
- {
- for (int j = 0; j < 16; j++)
- {
- if (differences[i][j] > threshold)
- diffPixels++;
- }
- }
- array_destroyer(differences, 16);
- array_destroyer(firstGrayScale, 16);
- array_destroyer(secondGrayScale, 16);
- float result = static_cast<float>(diffPixels) / 256; //diffPixels / 256f;
- return result;
- }
- Image* resize(Image* image)
- {
- Image* smallImage1 = new Bitmap(16, 16);
- // Resize images
- Graphics gr1(smallImage1);
- gr1.SetSmoothingMode(SmoothingModeHighQuality);
- gr1.SetInterpolationMode(InterpolationModeHighQualityBicubic);
- gr1.SetPixelOffsetMode(PixelOffsetModeHighQuality);
- gr1.DrawImage(image, 0, 0, 16, 16);
- return smallImage1;
- }
- //Converts an image to grayscale
- Image* get_gray_scale_version(Image* image)
- {
- //create a blank bitmap the same size as original
- INT width = image->GetWidth();
- INT height = image->GetHeight();
- Image* newImage = new Bitmap(width, height);
- Graphics grayGraphics(newImage);
- ColorMatrix colorMatrix = {
- 0.3f, 0.3f, 0.3f, 0.0f, 0.0f,
- 0.59f, 0.59f, 0.59f, 0.0f, 0.0f,
- 0.11f, 0.11f, 0.11f, 0.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 1.0f, 0.0f,
- 0.0f, 0.0f, 0.0f, 0.0f, 1.0f
- };
- //create some image attributes
- ImageAttributes imageAttributes;
- //set the color matrix attribute
- imageAttributes.SetColorMatrix(&colorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
- //draw the original image on the new image
- //using the grayscale color matrix
- grayGraphics.DrawImage(image, Rect(0, 0, width, height), 0, 0, width, height,
- UnitPixel, &imageAttributes);
- //delete &grayGraphics;
- return newImage;
- }
- void array_destroyer(::byte** ary, unsigned int dim1) {
- for (int i = 0; i < dim1; i++) {
- delete[] ary[i];
- }
- delete[] ary;
- }
- ::byte** array_generator(unsigned int dim1, unsigned int dim2) {
- ::byte** ptrary = new ::byte * [dim1];
- for (int i = 0; i < dim1; i++) {
- ptrary[i] = new ::byte[dim2];
- }
- return ptrary;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement