Prosty kod do sortowania zdjęć

0

Witam, próbowałem samemu kombinować, ale poddaje się.
Czy jest ktoś w stanie napisać mi naprawdę prosty kod na program w konsoli, który chwyta wszystkie zdjęcia .jpg/.png w folderze w którym znajdują się razem z tym programem, następnie tworzy 2 foldery ,,1'' i ,,2'', do folderu ,,1'' daje wszystkie zdjęcia o wymiarach 6000x4000, a do ,,2'' o wymiarach ,,4000x6000".
Wydaje mi się ze jest to banalne do zrobienia ale mi jakoś wyskakują błędy i ciezko mi uzyskać wlasnie takie efekt jak opisany powyżej :/

7

screenshot-20230915212006.png

2

Wybrałeś sobie dziki język do tego zadania — oskryptować to na szybko jakimś Pythonem czy innym Bashem by szło w moment, w C++ się trzeba trochę nagimnastykować…

No ale, poradnik gimnastyki — żeby się nie namęczyć, warto będzie skorzystać z gotowej biblioteki, na przykład tej: https://github.com/xiaozhuai/imageinfo Mała, tylko nagłówkowa (więc się nie trzeba nagimnastykować z linkowaniem i w ogóle), na licencji MIT, prosta w obsłudze.

Jak będziesz miał z nią jakieś konkretne problemy, to powiedz jakie, to spróbujemy Ci dalej pomóc — ale będziesz musiał zapytać konkretnie, pokazać kod, i w ogóle dać nam jakiś punkt zaczepienia…

0

Zmień sobie logikę sortowania i masz program który chciałeś. Chociaż już wiesz co można użyć. Program działa na Linuxie.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>

int main(int argc, char* argv[]) {
    if (argc != 2) {
        fprintf(stderr, "Użycie: %s ścieżka_do_katalogu\n", argv[0]);
        return 1;
    }

    const char* directoryPath = argv[1];
    DIR* dir = opendir(directoryPath);

    if (!dir) {
        perror("Nie można otworzyć katalogu");
        return 1;
    }

    struct dirent* entry;
    char command[512];

    while ((entry = readdir(dir))) {
        char filePath[512];
        sprintf(filePath, "%s/%s", directoryPath, entry->d_name);

        // Sprawdź, czy plik ma rozszerzenie .jpg lub .png
        if (strstr(entry->d_name, ".jpg") || strstr(entry->d_name, ".png")) {
            // Użyj programu ImageMagick do uzyskania rozmiarów obrazu
            sprintf(command, "identify -format '%%w %%h' \"%s\"", filePath);

            FILE* pipe = popen(command, "r");
            if (!pipe) {
                perror("Błąd podczas wywoływania ImageMagick");
                continue;
            }

            unsigned int width, height;
            if (fscanf(pipe, "%u %u", &width, &height) == 2) {
                pclose(pipe);

                char destinationPath[512];
                sprintf(destinationPath, "%s/%ux%u", directoryPath, width, height);

                // Sprawdź, czy katalog już istnieje
                struct stat destDirStat;
                if (stat(destinationPath, &destDirStat) == -1) {
                    // Katalog nie istnieje, więc tworzymy go
                    if (mkdir(destinationPath, 0755) == -1) {
                        perror("Błąd podczas tworzenia katalogu docelowego");
                        continue;
                    }
                }

                // Tworzenie ścieżki docelowej dla pliku
                char destinationFile[512];
                sprintf(destinationFile, "%s/%s", destinationPath, entry->d_name);

                // Przenoszenie pliku
                if (rename(filePath, destinationFile) == -1) {
                    perror("Błąd podczas przenoszenia pliku");
                } else {
                    printf("Przeniesiono plik %s do %s\n", entry->d_name, destinationFile);
                }
            } else {
                pclose(pipe);
                printf("Błąd podczas pobierania rozmiarów obrazu dla pliku %s\n", entry->d_name);
            }
        }
    }

    closedir(dir);
    return 0;
}
0

C++

#include <iostream>
#include <filesystem>
#include <opencv2/opencv.hpp>

namespace fs = std::filesystem;

int main() {
    std::string folder1 = "1";
    std::string folder2 = "2";

    // Tworzenie folderów 1 i 2
    fs::create_directory(folder1);
    fs::create_directory(folder2);

    // Przeszukiwanie aktualnego folderu w poszukiwaniu plików JPG i PNG
    for (const auto& entry : fs::directory_iterator(".")) {
        if (entry.is_regular_file()) {
            std::string filename = entry.path().filename().string();
            
            // Sprawdzenie rozszerzenia pliku
            if (filename.ends_with(".jpg") || filename.ends_with(".png")) {
                // Odczyt obrazu
                cv::Mat image = cv::imread(filename);

                if (!image.empty()) {
                    // Sprawdzenie wymiarów obrazu
                    int width = image.cols;
                    int height = image.rows;

                    if (width == 6000 && height == 4000) {
                        // Przeniesienie obrazu do folderu 1
                        fs::rename(filename, folder1 + "/" + filename);
                    } else if (width == 4000 && height == 6000) {
                        // Przeniesienie obrazu do folderu 2
                        fs::rename(filename, folder2 + "/" + filename);
                    }
                }
            }
        }
    }

    std::cout << "Zakonczono przetwarzanie." << std::endl;
    return 0;
}


python lepszy

import os
import shutil
from PIL import Image

# Tworzenie folderów "1" i "2"
folder1 = "1"
folder2 = "2"
os.makedirs(folder1, exist_ok=True)
os.makedirs(folder2, exist_ok=True)

# Przeszukiwanie aktualnego folderu w poszukiwaniu plików JPG i PNG
for filename in os.listdir("."):
    if filename.endswith((".jpg", ".png")):
        # Otwieranie obrazu za pomocą biblioteki PIL
        with Image.open(filename) as img:
            width, height = img.size

            if (width, height) == (6000, 4000):
                # Przeniesienie obrazu do folderu "1"
                shutil.move(filename, os.path.join(folder1, filename))
            elif (width, height) == (4000, 6000):
                # Przeniesienie obrazu do folderu "2"
                shutil.move(filename, os.path.join(folder2, filename))

print("Zakończono przetwarzanie.")


0
johnny_Be_good napisał(a):

Jednym postem skompromitowałeś kilka osób. Brawo.

O!
Odezwałeś się.

Czekamy na twoj kod we frameworku jak-mu-tam

3
Althorion napisał(a):

Wybrałeś sobie dziki język do tego zadania — oskryptować to na szybko jakimś Pythonem czy innym Bashem by szło w moment, w C++ się trzeba trochę nagimnastykować…

W tagu jest też C# (osobiście sądzę pytający nie odróżnia), ale to trop już lepszy, wyposażenie w biblioteki wiele lepsze, bezpieczniejsze kodowanie.

Karolitto24 napisał(a):

Witam, próbowałem samemu kombinować, ale poddaje się.

Chcesz być wiarygodny, pokaż te próby

0

masz jeszcze przykład w shellu ( ksh bo tego używam na codzień ). Musisz mieć ImageMagic
Wolne ale hehehe
Uwaga musisz być w dir w którym są zdjęcia które chcesz przesuwać.


#!/bin/ksh

mkdir '1' '2'

tf="$( mktemp )"
find . -type f -maxdepth 1 -iname '*.jpg' > "$tf"

while IFS= read -r imgfile
do

  width="$( identify -format "%[fx:w]" "$imgfile" )"
  height="$( identify -format "%[fx:h]" "$imgfile" )"

  printf "%s: %d x %d, " "$imgfile" "$width" "$height" >&2

  if (( ( width == 4000 ) && ( height == 6000 ) ))
  then
    mv "$imgfile" '1/'
    printf "moved to dir 1\n" >&2
  elif (( ( width == 6000  ) && ( height == 4000 ) ))
  then
    mv "$imgfile" '2/'
    printf "moved to dir 2\n" >&2
  else
    printf "left alone\n" >&2
  fi

done < "$tf"

rm -f "$tf"

ps na linuchu może być troche inna komenda dla image magic, np magic identify. Dunno

0

Do tak trywialnych zadań C++ jest jak wytaczanie armaty na wróbla.
Napisz to w Pythonie.

1

Do odczytywania wymiarów obrazka można by użyć lekkiej i wygodnej biblioteki nagłówkowej STB https://github.com/nothings/stb . Wystarczy skopiować do swojego projektu plik stb_image.h a potem w kodzie dołączyć tą bibliotekę nagłówkową w ten sposób:

#define STB_IMAGE_IMPLEMENTATION
#include "stb_image.h"

Pozostaje tylko wylistować pliki w katalogu i dla każdego z nich wywołać funkcję stbi_info, która zwróci wymiary obrazka:

int x,y,n,ok;
ok = stbi_info(filename, &x, &y, &n);
// returns ok=1 and sets x, y, n if image is a supported format, 0 otherwise.

Obsługuje PNG,JPG,BMP,TGA,GIF,PSD,...

1 użytkowników online, w tym zalogowanych: 0, gości: 1