Küçük dosyaları yok sayarken büyük dosyaları yeniden boyutlandırmak için mogrify kullanın


10

Aşağıdaki komutu çalıştırıyorum:

mogrify -resize '400x400>' *.png

">" İşaretine dikkat edin. Sözde, daha küçük dosyaları yok sayar, ancak yeniden boyutlandırmasa da, bunları düzenler (değişiklik tarihi ve dosya boyutu değiştirilir).

Aslında küçük dosyaları yalnız bırakmanın bir yolu var mı? Binlerce gereksiz yazma işleminden kaçınmak istiyorum.

Yanıtlar:


15

Bence mogrifysistematik olarak dosyayı yeniden yazar, bu yüzden tek umudunuz jippie tarafından önerildiği gibi, ilk listeyi filtrelemektir . Bunu şu şekilde yapabilirsiniz (denenmemiş): boyut göstergeli bir görüntü dosyası listesi yazdırın, yalnızca ilişkili boyutu aralık dahilinde olan adları saklayın ve bu listeyi işleyin.

identify -format '%w %h %i\n' ./*.png |
awk '$1 > 400 || $2 > 400 {sub(/^[^ ]* [^ ]* /, ""); print}' |
tr '\n' '\0' |
xargs -0 mogrify -resize '400x400'

Komut dosyası açıklaması:

  • Her dosya için genişlik, boşluk, yükseklik, boşluk ve dosya adıyla bir satır yazdırın. Sürümüne bağlı olarak identify, \nnihai bir satır ya gerekebilir (ImageMagick 6.6.0) ya da gereksiz ama zararsız (GraphicsMagick 1.1.11) ekleyin.
  • ( awk) Her satırda, width ( $1) ve height ( $2) gerekli koşullarla eşleşiyorsa:
    • İkinci boşluk karakterine kadar olan tüm metni kaldırın. Bu, genişliği ve yüksekliği keser.
    • Dosya adı olan satırın kalan kısmını yazdırın.
  • Yeni satırları boş karakterlerle değiştirin.
  • Dosya adlarında komutu xargs -0yürütmek için arayın mogrify. (Plain ( xargsboşluk \'") kullanamayız çünkü beyaz veya boşluk içeren girdilerle ilgilenemez .)

Dosya adları, yeni satırlar dışında herhangi bir karakter içerebilir.


Senaryoyu açıklayabilir misin? Özellikle "alt" kısım. Dosya adlarını boşluk bırakmadan yazdırıyor veya yeni bir satır ekliyor. mogrify: `22 553.png308 400 0134 2.png '@ hata / png.c / ReadPNGImage / 2951 dosyası açılamıyor. "308 400" ün nereden geldiği hakkında hiçbir fikrim yok. Dosyaların isimlerinde boşluklar olduğunu belirtmeliyim Teşekkürler.
Mike

Mogrifiye alıyorum: 340311 22 553.png308 400 0134 2.png '@ error / png.c / ReadPNGImage / 2951 dosyası açılamıyor. Komutu iki örnek dosyada 200x200 kullanarak çalıştırdım. 308x400'ün dosyalardan birinin boyutu olduğunu görüyorum
Mike

2
@ Ah Ah, anladım. Bazı sürümleri identifyher kayıttan sonra otomatik olarak bir satırsonu ekler, diğerlerinin açıkça bir tane olması gerekir. \nArgümanın sonuna -format(düzenleme bölümüne bakın) ekleyin .
Gilles 'SO- kötü olmayı bırak'

8

Tarif ettiğin aynı problemle karşılaştım. İşte benim çözümüm:

#!/bin/bash
files=*.jpg
minimumWidth=640
minimumHeight=640

for 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
    fi
done

Sanallaştırılmış CentOS 6.5 makinesinde birkaç JPEG görüntüsünde test ettim. Komut dosyası yalnızca genişliği veya yüksekliği 640 pikselden büyük olan görüntüleri yeniden boyutlandırdı ve sıkıştırdı. Bu, 800 x 600 (yatay, 640 x 480 olarak yeniden boyutlandırma) gibi boyutlara ve 600 x 800 (portre, 480 x 640 olarak yeniden boyutlandırma) gibi boyutlara sahip görüntüler için çalışmasını sağladı.

Not: 400x400Parametreye ilişkin bir not : mogrifyboyutları 400x400'e eşit veya küçük olsa bile dosyayı işleyecek, ancak boyutları 400x400'den büyük olduğunda yeniden boyutlandıracaktır . Bu yüzden dosyaların değişiklik zamanı ve boyutu değişir (benim durumumda, mogrifybu dosyaları olduğundan daha büyük hale getirdi ).


5

fxOperatörü, görüntüleri yükseklik / genişliğe göre filtrelemek için de kullanabilirsiniz.

identify -format '%[fx:(h>400 && w>400)]\n' image.png

irade çıktı 1görüntü daha büyük olması 400x400ve 0bunun eşit veya küçükse 400x400...


(Hiçbir satırsonu / boşluk / sekmeler vb) kullanabilirdin aklı başında dosyaları isimleri varsayarsak identifyya öncesinde görüntü adlarını yazdırmak 1:veya 0:ile başlayan satırları silme çıktıyı işleyecek, 0:ve kaldırma lider 1:dosya adları kalır böylece sadece hatların geri kalanı üzerinde bir ardından bu listeyi ekleyin mogrify ... @-( @sözdizimi eklendi imagemagick v6.5.2):

identify -format '%[fx:(h>400 && w>400)]:%i\n' ./*.png | \
sed '/^1:/!d;//s///' | mogrify -resize '400x400' -- @-

Aksi takdirde, findyalnızca> 400x400 boyutundaki dosyaları yazdırabilir ve ardından sonucu xargs+ olarak işaretleyebilirsiniz mogrify(her dosya için bir kabuk çalıştırdığından daha az verimlidir, ancak her türlü dosya adıyla çalışmalıdır):

find . -maxdepth 1 -type f -name '*.png' -exec sh -c \
'identify -format "%[fx:(h>400 && w>400)]\n" "$0" | grep -q 1' {} \; -print0 \
| xargs -0 mogrify -resize '400x400'

Eğer zshkullanıcıysanız bu yanıta da bakınız .


3

Resminizin boyutunu bulmak ve küçük bir komut dosyasından düzenlemek isteyip istemediğinize karar vermek için tanımlamayı kullanmaya ne dersiniz:

identify -format "width=%w heigth=%h" bootchart.png 
width=3853 heigth=10092

Basit bir komut dosyasında kullanmak için çıktı biçimini düzenlemek çok zor olmamalıdır.


Sınırlı becerilerim ve görüntülerin boyutlarının çok düzensiz olduğu düşünüldüğünde, daha basit bir yönteme ihtiyacım var. Hepsini mogrify ile işlemeyi tercih ederim.
Mike

0

Ben böyle bir PHP-script kullanın, ImageMagick kullanır:

<?php
$dir = ".";
$exts = array('jpg', 'jpeg', 'png', 'gif');
$max_size = is_numeric($argv[1]) ? $argv[1] : 3000;
$morgify = "mogrify -verbose -scale \"${max_size}x${max_size}>\" -quality 85";
$identify = "identify -format \"%wx%h\"";

$dh = opendir($dir);
while (($file = readdir($dh)) !== false) {
    $path = "$dir/$file";
    // skip no images
    $dot = strrpos($file, '.');
    $ext = strtolower(substr($file, $dot + 1));
    if (!in_array($ext, $exts)) continue;
    // large size?
    $size = exec("$identify \"$path\"");
    list($width, $height) = explode('x', trim($size));
    if (max($width, $height) > $max_size) {
        // scale!
        print "scale $file ${width}x${height}";
        exec("$morgify \"$path\"");
        print "\n";
    }
}
closedir($dh);
?>

Mevcut dizindeki tüm görüntüleri bir kenarda 3000'den büyük ölçeklendirir.

Komutu çalıştır: php scale.phpVEYAphp scale.php 2000


0

İşte @ArionKrause ve @don_crissti'den fikirleri bir araya getirerek:

#!/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

(En sevdiğim toplu işlemcim Phatch, Ubuntu 16.04 ile çalışmadığı için buna ihtiyacım vardı.)


0

Yeniden boyutlandırma ve optimize etme işlevlerim

resize_and_optimize_images () {
  resize_images 700 $PWD
  optimize_images 85 $PWD
}

resize_images () {
  max="$1"
  dir="$2"

  echo "Resizing dir $dir, max size - $max"

  shopt -s globstar

  for f in $dir/**/*.jpg $dir/**/*.jpeg $dir/**/*.png ; do
    echo "Checking $f"
    s=`identify -format "%w" $f`

    if [ $s -gt $max ]; then
      echo "Resizing..."
      mogrify -verbose -resize $max $f
    fi
    echo
  done

  echo "Done resizing dir $dir"
}

optimize_images () {
  quality="$1"
  dir="$2"

  echo "Optimizing dir $dir, quality - $quality"

  docker run -it --rm --name optimize_images_foo \
    -v $dir:/usr/src/app \
    -w /usr/src/app ruby:2.4-stretch bash -c \
    "gem install image_optim image_optim_pack && \
    (curl -L \"http://static.jonof.id.au/dl/kenutils/pngout-20150319-linux.tar.gz\" | tar -xz -C /usr/bin --strip-components 2 --wildcards \"*/x86_64/pngout\") && \
    image_optim --verbose --allow-lossy --jpegoptim-allow-lossy true --jpegoptim-max-quality $quality --pngquant-allow-lossy true --pngquant-quality 0..$quality -r ."

  echo "Done optimizing dir $dir"
}
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.