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 :/
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…
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;
}
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.")
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
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
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
Do tak trywialnych zadań C++ jest jak wytaczanie armaty na wróbla.
Napisz to w Pythonie.
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,...