mogrifyを使用して小さなファイルを無視しながら大きなファイルのサイズを変更する


10

次のコマンドを実行しています。

mogrify -resize '400x400>' *.png

「>」に注意してください。おそらくそれは小さなファイルを無視しますが、それらはサイズ変更されませんが、それらを編集します(変更日とファイルサイズが変更されます)。

実際に小さいファイルをそのままにしておく方法はありますか?数千の不要な書き込み操作を回避したいと思います。

回答:


15

私はmogrify体系的にファイルを書き換えると思いますので、あなたの唯一の望みはjippieが示唆するように、最初にリストをフィルタリングすることです。以下はその方法です(テストされていません)。サイズを示す画像ファイルのリストを印刷し、関連するサイズが範囲内にある名前のみを保持して、そのリストを処理します。

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

スクリプトの説明:

  • ファイルごとに、幅、スペース、高さ、スペース、およびファイル名を含む行を印刷します。バージョンに応じてidentify\n最後の改行は、いずれかの必要があるかもしれない(ImageMagickの6.6.0)または余分が、無害(GraphicsMagickの1.1.11)を追加します。
  • awk)各行で、幅($1)と高さ($2)が必要な条件に一致する場合:
    • 2番目のスペース文字までのすべてのテキストを削除します。これにより、幅と高さが取り除かれます。
    • 行の残りの部分、つまりファイル名を出力します。
  • 改行をヌル文字に置き換えます。
  • を呼び出しxargs -0mogrify、ファイル名に対してコマンドを実行します。(xargs空白またはを含む入力を処理できないため、プレーンは使用できません\'"。)

ファイル名には、改行以外の任意の文字を含めることができます。


そのスクリプトを説明できますか?特に「サブ」部分。スペースなしでファイル名を印刷するか、新しい行を挿入します。mogrify:ファイル `22 553.png308 400 0134 2.png 'を開くことができません@ error / png.c / ReadPNGImage / 2951。その「308 400」がどこから来たのか私にはわかりません。ファイルの名前にスペースが含まれていることに言及しましょう。ありがとうございます。
マイク

私はmogrifyを取得しています:ファイル `340 271 22 553.png308 400 0134 2.png '@ error / png.c / ReadPNGImage / 2951を開けません。2つのサンプルファイルで200x200を使用してコマンドを実行しました。308x400が1つのファイルのサイズであることがわかります
Mike

2
@マイクああ、それを得た。一部のバージョンでidentifyは、各レコードの後に自動的に改行が挿入されますが、他のバージョンでは明示的に改行する必要があります。\nへの引数の最後に追加します-format(私の編集を参照)。
Gilles「SO-悪をやめなさい」

8

あなたが説明したのと同じ問題に直面しました。これが私の解決策です:

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

仮想化されたCentOS 6.5マシン上のいくつかのJPEGイメージでテストしました。スクリプトは、幅または高さが640ピクセルを超える画像のサイズ変更と圧縮のみを行いました。これにより、800 x 600(横長、640 x 480にサイズ変更)のような寸法と600 x 800(縦長、480 x 640にサイズ変更)のような寸法の画像で機能しました。

PS:400x400パラメータに関する注意:mogrifyファイルのサイズが400x400以下であってもファイルを処理しますが、サイズが400x400より大きい場合にのみサイズを変更します。そのため、ファイルの変更時刻とサイズが変更されます(私の場合、mogrifyこれらのファイルをさらに大きくしました)。


5

fx演算子を使用して、高さ/幅に基づいて画像をフィルタリングすることもできます。

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

意志出力1画像がより大きい場合400x4000、それは同じかよりも小さいなら400x400...


正しいファイル名(改行/スペース/タブなどなし)を想定identifyして、1:または0:で始まる画像名を印刷し、出力を処理して0:、先頭の行を削除1:し、残りの行の先頭を削除して、ファイル名のみが残るようにします。行ごとに、そのリストをパイプしますmogrify ... @-@構文はで追加されましたimagemagick v6.5.2)。

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

それ以外の場合は、findサイズが400x400より大きいファイルのみを印刷してから、結果をxargs+にパイプすることがmogrifyできます(ファイルごとにシェルを実行するため、効率が低下しますが、あらゆる種類のファイル名で機能するはずです)。

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'

zshユーザーの場合は、この回答も参照してください。


3

特定を使用して画像のサイズを見つけ、編集するかどうかを小さなスクリプトから決定するのはどうですか?

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

単純なスクリプトで使用するために出力形式を編集するのは難しくありません。


私の限られたスキルと画像のサイズが非常に不規則であることを考えると、もっと簡単な方法が必要です。それらすべてをmogrifyで処理したい。
マイク

0

私はそのようなPHPスクリプトを使用していますが、ImageMagickを使用しています。

<?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);
?>

現在のディレクトリにあるすべての画像を、一部のエッジで3000よりも大きくスケーリングします。

コマンドを実行:php scale.phpまたはphp scale.php 2000


0

@ArionKrauseと@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

(私のお気に入りのバッチプロセッサPhatchはUbuntu 16.04では機能しないため、これが必要でした。)


0

サイズを変更して最適化する私の機能

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"
}
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.