使用 mogrify 调整大文件大小而忽略小文件

Mik*_*ike 12 find mogrify

我正在运行以下命令:

mogrify -resize '400x400>' *.png
Run Code Online (Sandbox Code Playgroud)

注意“>”。据说它会忽略较小的文件,但虽然它不会调整它们的大小,但它会编辑它们(修改日期和文件大小已更改)。

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

Gil*_*il' 16

我认为mogrify系统地重写了文件,所以你唯一的希望是按照jippie 的建议先过滤列表。以下是您可以这样做的方法(未经测试):打印出带有大小指示的图像文件列表,仅保留相关大小在范围内的名称,然后处理该列表。

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

脚本说明:

  • 对于每个文件,打印一行,其中包含宽度、空格、高度、空格和文件名。根据您的 版本identify\n添加最终换行符可能是必要的(ImageMagick 6.6.0)或多余但无害的(GraphicsMagick 1.1.11)。
  • ( awk) 在每一行上,如果宽度 ( $1) 和高度 ( $2) 符合要求的条件,则:
    • 删除直到第二个空格字符的所有文本。这将去除宽度和高度。
    • 打印该行的剩余部分,即文件名。
  • 用空字符替换换行符。
  • 调用xargs -0mogrify对文件名执行命令。(我们不能使用普通的,xargs因为它无法处理包含空格或\'". 的输入。)

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

  • @Mike啊,明白了。某些版本的 `identify` 会自动在每条记录后放置一个换行符,而其他版本则需要明确地放置一个换行符。在参数末尾添加 `\n` 到 `-format`(见我的编辑)。 (2认同)

小智 11

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

#!/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
Run Code Online (Sandbox Code Playgroud)

我在一台虚拟化的 CentOS 6.5 机器上对几个 JPEG 图像进行了测试。该脚本仅调整和压缩宽度或高度大于 640 像素的图像。这使它适用于尺寸为 800 x 600(横向,将其调整为 640 x 480)和尺寸为 600 x 800(纵向,将其调整为 480 x 640)的图像。

PS:关于400x400参数的说明:mogrify即使文件的尺寸等于或小于400x400也会处理文件,但仅当其尺寸大于400x400时才会调整大小。这就是为什么文件的修改时间和大小会发生变化(在我的情况下,mogrify使这些文件比原来更大)。


don*_*sti 5

您还可以使用fx运算符根据高度/宽度过滤图像,例如

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

将输出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' -- @-
Run Code Online (Sandbox Code Playgroud)

否则,find您只能打印大小 > 400x400 的文件,然后将结果通过管道传送到xargs+ mogrify(效率较低,因为它为每个文件运行一个 shell,但它应该适用于所有类型的文件名):

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'
Run Code Online (Sandbox Code Playgroud)

如果您是zsh用户,请参阅此答案