使用 mogrify 调整大图像的大小,同时忽略小图像

使用 mogrify 调整大图像的大小,同时忽略小图像

我正在运行以下命令:

mogrify -resize '400x400>' *.png

根据文档,“widthxheight>”几何图形(>末尾带有)“缩小尺寸大于相应宽度和/或高度参数的图像。”

我希望宽度/高度小于 400x400 的图像不会受到影响,但是 mogrify 无缘无故地重写了文件——修改日期和文件大小都改变了。

有没有办法让它实际上只留下较小的图像?我想避免数千次不必要的写入操作。

答案1

我认为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) 符合要求的条件,则:
    • 删除第二个空格字符之前的所有文本。这会去除宽度和高度。
    • 打印该行的剩余部分,即文件名。
  • 用空字符替换换行符。
  • 调用以对文件名xargs -0执行命令。 mogrify(我们不能使用 plain,xargs因为它无法处理包含空格或 的输入\'"。)

文件名可以包含除换行符之外的任何字符。

答案2

我遇到了你所描述的同样的问题。这是我的解决方案:

#!/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:参数说明400x400mogrify即使文件尺寸等于或小于 400x400,也会处理该文件,但会调整大小仅当其尺寸大于 400x400 时。这就是为什么文件的修改时间和大小被改变(在我的例子中,mogrify使这些文件甚至更大比他们)。

答案3

imagemagick fx运算符允许根据高度/宽度过滤图像,例如

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

内部命令将输出1图像是否大于400x4000等于或小于,400x400因此表达式将分别(( ))计算为和。因此,您可以迭代文件并运行此测试,将正数添加到数组中,然后将其作为参数传递给数组:truefalsemogrify

args=()
for f in ./*.png
do
(( $(identify -format '%[fx:(h>400 && w>400)]' "$f") )) && args+=("$f"}
done
mogrify -resize '400x400' "$args[@]"

如果您是zsh用户,另请参阅这个答案

答案4

这是我的看法,融合了 @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。)

相关内容