我正在尝试编写一个bash脚本来修剪很久以前扫描的一些旧照片周围的扫描仪空白区域。我有数百张照片,所以我不是手动做的。 Fred的imagemagick脚本无法选择合适的区域。
我不是程序员,所以请不要因我在脚本编写方面的可怕尝试而感到冒犯!
我找到了使用imagemagick的命令组合。
首先我使用模糊滤镜来混淆imagemagick以正确选择照片尺寸:
convert input -virtual-pixel edge -blur 0x15 -fuzz 15% -trim info:
这会将数据吐出如下:
0001.jpeg JPEG 3439x2437 4960x6874+1521+115 8-bit DirectClass 0.070u 0:00.009
然后我使用这些数字进行裁剪,这在我的扫描中非常准确。以下是使用上述数字的示例。
convert inputfile -crop 3439x2437+1521+115 +repage outputfile
我的问题是编写bash文件来浏览图片目录并自动执行该过程。
这是我到目前为止所拥有的:
#!/bin/bash
ls *.jpeg > list
cat list | while read line; do
convert $line -virtual-pixel edge -blur 0x15 -fuzz 15% -trim info: > blurtrim.txt
#need a line to manipulate the output of the above to spit out the crop coordinates for the next command
crop=$(<crop.txt)
convert $line -crop $crop +repage trim$line.jpeg
rm blurtext.txt
rm crop.txt
done
rm list
我不能做的关键是改变第一个imagemagick命令的字符串输出。
该文件沿着以下行:
输入fileformat 1111x2222 3333x4444 + 5555 + 666然后加载一堆废话我不在乎
我的脚本中需要的数字是: 1111X2222 + 5555 + 666
顶部的樱桃是大多数数字是四位数而不是所有数字都是如此,所以我不能依赖它。
关于如何使用sed或者最好使用其他不那么恶魔来获取上述数字的任何想法?
对语法的解释会很好(但是我理解,如果解释是一本书的大小,那么最好省略)。
提前感谢!
答案 0 :(得分:2)
你不需要解析任何东西! ImageMagick可以使用/node1/node2/node3[condition/task[@name='task1' and @value='abc'] and condition/task[@name='task2' and @value='efg'] and condition/task[@name='task5' and @value='nop']]/id
格式直接告诉您修剪框:
%@
所以,你可以说:
convert image.jpg -virtual-pixel edge -blur 0x15 -fuzz 15% -format "%@" info:
1111x2222+5555+666
好处包括这种方法也适用于Windows,没有trimbox=$(convert image.jpg -virtual-pixel edge -blur 0x15 -fuzz 15% -format "%@" info:)
convert image.jpg -crop $trimbox ...
。
因此,完整的解决方案将是:
sed
答案 1 :(得分:1)
<强>解决方案强>
这将逐行解析您的文件,提取所需的参数,将它们连接在一起,并将其用作参数值来“裁剪”。对于convert
计划:
regex='([0-9]+x[0-9]+) [0-9]+x[0-9]+\+([0-9]+\+[0-9]+)'
while read line
do
if [[ $line =~ $regex ]]
then
cropParam="${BASH_REMATCH[1]}+${BASH_REMATCH[2]}"
convert inputfile -crop $cropParam +repage outputfile
else
echo "ERROR: Line was not in the expected format ($line)"
exit 1;
fi
done < blurtrim.txt
<强>解释强>
regex
变量包含一个正则表达式(bash中的正则表达式简介:http://www.tldp.org/LDP/abs/html/x17129.html),它描述了您在问题中描述的数字的格式。模式周围的()
部分表示称为捕获组的东西。如果模式匹配,则第一个()
中的部分将在bash变量BASH_REMATCH[1]
中捕获,而第二个()
将在BASH_REMATCH[2]
中捕获。 BASH_REMATCH[0]
包含整个匹配项,以防您想知道我们为什么从索引1开始。
行[[ $line =~ $regex ]]
实际上是为我们执行模式匹配算法的。在Bash [[
中称为扩展测试命令,而操作符=~
称为正则表达式匹配运算符。本文更详细地解释了运算符:http://www.linuxjournal.com/content/bash-regular-expressions。
答案 2 :(得分:0)
我会向乔纳森提出一个类似的解决方案:
re='([0-9x]+) [0-9x]+(\+[0-9+]+)'
for file in *.jpeg; do
output=$(convert "$file" -virtual-pixel edge -blur 0x15 -fuzz 15% -trim info:)
if [[ $output =~ $re ]]; then
crop="${BASH_REMATCH[1]}${BASH_REMATCH[2]}"
convert "$file" -crop "$crop" +repage "trim$file.jpeg"
fi
done
正则表达式捕获包含0-9
或x
范围内的所有字符的组,然后是+
后跟数字和+
字符的字符。这是一个不太严格的模式,因为它在括号表达式中包含x
和+
,因此在技术上会允许0x9x9x0
这样的内容,但我无法想象这会出现基于您向我们展示的输出的问题。
此尝试与原始尝试之间的其他差异是,没有创建临时文件,并且循环在文件列表上运行,而不是使用ls
,the parsing of which should generally be avoided in scripts。