Użyj mogrify, aby zmienić rozmiar dużych plików, ignorując małe
10
Korzystam z następującego polecenia:
mogrify -resize '400x400>' *.png
Zwróć uwagę na „>”. Podobno zignoruje mniejsze pliki, ale chociaż nie zmienia ich rozmiaru, edytuje je (data modyfikacji i rozmiar pliku są zmieniane).
Czy istnieje sposób, aby faktycznie zostawić mniejsze pliki w spokoju? Chciałbym uniknąć kilku tysięcy niepotrzebnych operacji zapisu.
Myślę, że mogrifysystematycznie przepisuje plik, więc jedyną nadzieją jest, aby najpierw przefiltrować listę, jak sugeruje jippie . Oto, jak możesz to zrobić (niesprawdzone): wydrukuj listę plików graficznych ze wskazaniem rozmiaru, zachowaj tylko nazwy, których powiązany rozmiar jest w zasięgu, i przetworz tę listę.
Dla każdego pliku wydrukuj linię o szerokości, spacji, wysokości, spacji i nazwie pliku. W zależności od wersji identify, \ndodać końcowy znak nowej linii może być albo konieczne (ImageMagick 6.6.0) lub zbędne ale nieszkodliwe (GraphicsMagick 1.1.11).
( awk) W każdej linii, jeśli szerokość ( $1) i wysokość ( $2) odpowiadają wymaganym warunkom, wówczas:
Usuń cały tekst do drugiego znaku spacji. To usuwa szerokość i wysokość.
Wydrukuj resztki wiersza, czyli nazwę pliku.
Zamień znaki nowej linii na znaki puste.
Zadzwoń, xargs -0aby wykonać mogrifypolecenie na nazwach plików. (Nie możemy używać zwykłego, xargsponieważ nie radzi sobie z danymi wejściowymi zawierającymi białe znaki lub \'".)
Nazwy plików mogą zawierać dowolny znak oprócz nowego wiersza.
czy możesz wyjaśnić ten skrypt? W szczególności część „podrzędna”. Drukuje nazwy plików bez spacji lub wstawia nowy wiersz. mogrify: nie można otworzyć pliku `22 553.png308 400 0134 2.png '@ error / png.c / ReadPNGImage / 2951. Nie mam pojęcia, skąd pochodzi ten „308 400”. Powinienem wspomnieć, że pliki mają spacje w nazwach. Dziękujemy.
Mike
Mam problemy: nie mogę otworzyć pliku `340 271 22 553.png308 400 0134 2.png '@ error / png.c / ReadPNGImage / 2951. Uruchomiłem polecenie przy użyciu 200 x 200 na dwóch przykładowych plikach. Widzę, że rozmiar 308 x 400 jest wielkości jednego z plików
Mike
2
@ Mike Ah, rozumiem. Niektóre wersje identifyautomatycznie umieszczają nowy wiersz po każdym rekordzie, inne muszą mieć go wyraźnie. Dodaj \nna końcu argumentu do -format(patrz moja edycja).
Gilles „SO- przestań być zły”
8
Napotkałem ten sam problem, który opisałeś. Oto moje rozwiązanie:
#!/bin/bash
files=*.jpg
minimumWidth=640
minimumHeight=640for f in $files
do
imageWidth=$(identify -format "%w""$f")
imageHeight=$(identify -format "%h""$f")if["$imageWidth"-gt "$minimumWidth"]||["$imageHeight"-gt "$minimumHeight"];then
mogrify -resize ''"$minimumWidth"x"$minimumHeight"'' $f
fidone
Przetestowałem to na kilku obrazach JPEG na zwirtualizowanym komputerze CentOS 6.5. Skrypt zmienił tylko rozmiar i skompresował obrazy, których szerokość lub wysokość była większa niż 640 pikseli. Dzięki temu działa dla obrazów o wymiarach takich jak 800 x 600 (poziomy, zmiana rozmiaru na 640 x 480) i wymiarach takich jak 600 x 800 (pionowy, zmiana rozmiaru na 480 x 640).
PS: Uwaga na temat 400x400parametru: mogrifyprzetworzy plik, nawet jeśli jego wymiary są równe lub mniejsze niż 400 x 400, ale zmieni rozmiar, tylko jeśli jego wymiary są większe niż 400 x 400. Dlatego czas i rozmiar modyfikacji plików są zmieniane (w moim przypadku mogrifypliki te są jeszcze większe niż były).
wyświetli się, 1jeśli obraz jest większy niż 400x400i 0jeśli jest równy lub mniejszy niż 400x400...
Zakładając, że przy zdrowych nazwach plików (bez nowych linii / spacji / tabulatorów itp.) Możesz użyć identifydo wydrukowania nazw obrazów poprzedzonych jednym z nich 1:lub 0:przetworzyć wyjściowe linie usuwające, które zaczynają się od 0:i usuwając wiodące 1:linie na pozostałych liniach, aby pozostały tylko nazwy plików, jeden w wierszu, a następnie potokuj tę listę do mogrify ... @-( dodano @składnięimagemagick v6.5.2 ):
W przeciwnym razie findmożesz wydrukować tylko pliki o rozmiarze> 400x400, a następnie potokować wynik do xargs+ mogrify(jest mniej wydajny, ponieważ uruchamia powłokę dla każdego pliku, ale powinien działać z wszystkimi rodzajami nazw plików):
Biorąc pod uwagę moje ograniczone umiejętności i fakt, że rozmiary obrazów są tak nieregularne, potrzebuję prostszej metody. Wolę przetwarzać je wszystkie z niedowierzaniem.
Oto moje zdanie na ten temat, zawierające pomysły z @ArionKrause i @don_crissti:
#!/bin/bash
# adapted from http://unix.stackexchange.com/a/157594/110635
# and http://unix.stackexchange.com/a/220619/110635
W=1024
H=768
SIZE_TEST="%[fx:(h>$H && w>$W)]"'\n'
for f in $*; do
if [ $(identify -format "$SIZE_TEST" "$f") = 1 ]; then
echo "Resize: $f"
mogrify -resize ''"$W"x"$H"'' "$f"
else
echo "Do not resize: $f"
fi
done
(Potrzebowałem tego, ponieważ mój ulubiony procesor wsadowy Phatch nie działa z Ubuntu 16.04.)
identify
automatycznie umieszczają nowy wiersz po każdym rekordzie, inne muszą mieć go wyraźnie. Dodaj\n
na końcu argumentu do-format
(patrz moja edycja).Napotkałem ten sam problem, który opisałeś. Oto moje rozwiązanie:
Przetestowałem to na kilku obrazach JPEG na zwirtualizowanym komputerze CentOS 6.5. Skrypt zmienił tylko rozmiar i skompresował obrazy, których szerokość lub wysokość była większa niż 640 pikseli. Dzięki temu działa dla obrazów o wymiarach takich jak 800 x 600 (poziomy, zmiana rozmiaru na 640 x 480) i wymiarach takich jak 600 x 800 (pionowy, zmiana rozmiaru na 480 x 640).
PS: Uwaga na temat
400x400
parametru:mogrify
przetworzy plik, nawet jeśli jego wymiary są równe lub mniejsze niż 400 x 400, ale zmieni rozmiar, tylko jeśli jego wymiary są większe niż 400 x 400. Dlatego czas i rozmiar modyfikacji plików są zmieniane (w moim przypadkumogrify
pliki te są jeszcze większe niż były).źródło
Możesz także użyć
fx
operatora do filtrowania obrazów na podstawie wysokości / szerokości, npwyświetli się,
1
jeśli obraz jest większy niż400x400
i0
jeśli jest równy lub mniejszy niż400x400
...Zakładając, że przy zdrowych nazwach plików (bez nowych linii / spacji / tabulatorów itp.) Możesz użyć
identify
do wydrukowania nazw obrazów poprzedzonych jednym z nich1:
lub0:
przetworzyć wyjściowe linie usuwające, które zaczynają się od0:
i usuwając wiodące1:
linie na pozostałych liniach, aby pozostały tylko nazwy plików, jeden w wierszu, a następnie potokuj tę listę domogrify ... @-
( dodano@
składnięimagemagick v6.5.2
):W przeciwnym razie
find
możesz wydrukować tylko pliki o rozmiarze> 400x400, a następnie potokować wynik doxargs
+mogrify
(jest mniej wydajny, ponieważ uruchamia powłokę dla każdego pliku, ale powinien działać z wszystkimi rodzajami nazw plików):Jeśli jesteś
zsh
użytkownikiem, zobacz również tę odpowiedź .źródło
Co powiesz na użycie identyfikatora, aby znaleźć rozmiar obrazu i zdecydować na podstawie małego skryptu, czy chcesz go edytować, czy nie:
Edytowanie formatu wyjściowego do użycia w prostym skrypcie nie powinno być trudne.
źródło
Używam takiego skryptu PHP, używa ImageMagick:
Na pewnym brzegu skaluje wszystkie obrazy w bieżącym katalogu większe niż 3000.
Uruchom polecenie:
php scale.php
ORphp scale.php 2000
źródło
Oto moje zdanie na ten temat, zawierające pomysły z @ArionKrause i @don_crissti:
(Potrzebowałem tego, ponieważ mój ulubiony procesor wsadowy Phatch nie działa z Ubuntu 16.04.)
źródło
Moje funkcje do zmiany rozmiaru i optymalizacji
źródło