Answers:
我认为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
因为它不能处理包含空格或的输入\'"
。)文件名可以包含除换行符以外的任何字符。
identify
自动在每条记录后添加换行符,其他版本则需要明确地使用换行符。\n
在参数末尾添加到-format
(请参阅我的编辑)。
我遇到了您描述的相同问题。这是我的解决方案:
#!/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
使这些文件比以前更大)。
您还可以使用fx
运算符根据高度/宽度过滤图像,例如
identify -format '%[fx:(h>400 && w>400)]\n' image.png
1
如果图像大于400x400
且0
等于或小于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
(效率较低,因为它会为每个文件运行一个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'
如果您是zsh
用户,请参见此答案。
我使用这样的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
这是我的观点,结合了@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上使用。)
我要调整大小和优化的功能
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"
}