问题描述
我使用以下命令将目录中的所有jpg
文件转换并合并为单个pdf文件。
convert *.jpg file.pdf
目录中的文件从1.jpg
编号到123.jpg
。转换很顺利,但转换后页面都混淆了。我希望pdf的页面从1.jpg
到123.jpg
的顺序与它们的命名顺序相同。我也尝试使用以下命令:
cd 1
FILES=$( find . -type f -name "*jpg" | cut -d/ -f 2)
mkdir temp && cd temp
for file in $FILES; do
BASE=$(echo $file | sed 's/.jpg//g');
convert ../$BASE.jpg $BASE.pdf;
done &&
pdftk *pdf cat output ../1.pdf &&
cd ..
rm -rf temp
但仍然没有运气。操作平台Linux。
最佳解决方法
问题是因为你的shell正在以纯字母顺序扩展通配符,并且因为数字的长度不同,顺序将是不正确的:
$ echo *.jpg
1.jpg 10.jpg 100.jpg 101.jpg 102.jpg ...
解决方案是根据需要用零填充文件名,以便在运行convert命令之前它们的长度相同:
$ for i in *.jpg; do num=`expr match "$i" '\([0-9]\+\).*'`;
> padded=`printf "%03d" $num`; mv -v "$i" "${i/$num/$padded}"; done
现在文件将以正确的顺序与通配符匹配,为convert命令做好准备:
$ echo *.jpg
001.jpg 002.jpg 003.jpg 004.jpg 005.jpg 006.jpg 007.jpg 008.jpg ...
次佳解决方法
或者只需阅读ls
手册并查看:
-v natural sort of (version) numbers within text
所以,在单一命令中做我们需要的。
convert `ls -v *.jpg` foobar.pdf
玩得开心;)F。
第三种解决方法
我是这样做的:第一行将所有jpg文件转换为pdf,它使用convert命令。第二行是将所有pdf文件合并为一页,每页为pdf。这是使用gs((PostScript和PDF语言解释器和预览器))
for i in $(find . -maxdepth 1 -name "*.jpg" -print); do convert $i ${i//jpg/pdf}; done
gs -dNOPAUSE -sDEVICE=pdfwrite -sOUTPUTFILE=merged_file.pdf -dBATCH `find . -maxdepth 1 -name "*.pdf" -print"`
第四种方法
你可以用
convert '%d.jpg[1-132]' file.pdf
通过https://www.imagemagick.org/script/命令行-processing.php:
Another method of referring to other image files is by embedding a formatting character in the filename with a scene range. Consider the filename
image-%d.jpg[1-5]
. The command
magick image-%d.jpg[1-5]
causes ImageMagick to attempt to read images with these filenames:
image-1.jpg image-2.jpg image-3.jpg image-4.jpg image-5.jpg
另请参见https://www.imagemagick.org/script/convert.php
第五种方法
当我想合并许多high-resolution jpeg图像(来自扫描的书籍)时,上述所有答案都失败了。
Imagemagick尝试将所有文件加载到RAM中,因此我使用了以下two-step方法:
find -iname "*.JPG" | xargs -I'{}' convert {} {}.pdf
pdfunite *.pdf merged_file.pdf
请注意,使用此方法,您还可以使用GNU parallel来加速转换:
find -iname "*.JPG" | parallel -I'{}' convert {} {}.pdf