在 Linux 中将多个 jpg 合并为单个 pdf
Posted
技术标签:
【中文标题】在 Linux 中将多个 jpg 合并为单个 pdf【英文标题】:Merge multiple jpg into single pdf in Linux 【发布时间】:2012-11-17 01:56:51 【问题描述】:我使用以下命令将目录中的所有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。
【问题讨论】:
代表用户 sindhus 添加评论,该用户没有足够的评论点数(见下文):convert
命令是 imagemagick
包的一部分。
错误:convert-im6.q16:尝试执行安全策略“PDF”不允许的操作
如果您遇到安全策略问题,请参阅:askubuntu.com/a/1081907/281163
【参考方案1】:
结合 Felix Defrance 和 Delan Azabani 的回答(从上面):
convert `for file in $FILES; do echo $file; done` test_2.pdf
【讨论】:
【参考方案2】:如何从图像列表创建 PDF 文档
第 1 步:从存储库安装
parallel
。这将加快进程
第 2 步:将每个 jpg 转换为 pdf 文件
find -iname "*.JPG" | sort -V | parallel -I'' convert -compress jpeg -quality 25 .pdf
sort -V
将按自然顺序对文件名进行排序。
第 3 步:将所有 PDF 合并为一个
pdfunite $(find -iname '*.pdf' | sort -V) output_document.pdf
信用Gregor Sturm
【讨论】:
【参考方案3】:当我想合并许多高分辨率 jpeg 图像(来自扫描的书)时,上述所有答案对我来说都失败了。
Imagemagick 尝试将所有文件加载到 RAM 中,因此我使用了以下两步方法:
find -iname "*.JPG" | xargs -I'' convert .pdf
pdfunite *.pdf merged_file.pdf
请注意,通过这种方法,您还可以使用 GNU 并行来加速转换:
find -iname "*.JPG" | parallel -I'' convert .pdf
【讨论】:
【参考方案4】:你可以使用
convert '%d.jpg[1-132]' file.pdf
通过https://www.imagemagick.org/script/command-line-processing.php:
引用其他图像文件的另一种方法是嵌入 带有场景范围的文件名中的格式化字符。考虑 文件名
image-%d.jpg[1-5]
。命令
magick image-%d.jpg[1-5]
导致 ImageMagick 尝试读取图像 使用这些文件名:
image-1.jpg image-2.jpg image-3.jpg image-4.jpg image-5.jpg
另见https://www.imagemagick.org/script/convert.php
【讨论】:
【参考方案5】:或者只是阅读ls
手册并查看:
-v 文本中(版本)数字的自然排序
所以,在单个命令中执行我们需要的操作。
convert `ls -v *.jpg` foobar.pdf
玩得开心;) F.
【讨论】:
@Jason:它有效(+1)。但是您最终是否忘记了大多数数码相机将其图像存储为*.JPG
而不是*.jpg
?
当文件名中有空格时失败,除了那个大拇指! :))
请注意,这是 GNU ls 的功能,而不是 BSD ls。安装 GNU coreutils 以在 BSD 系列和 OS X 上获取 GNU ls。
如果您生成图像的另一个好方法是使用ls -t
标志按修改时间排序。此外,-r
标志颠倒了顺序。
这是一个很好的解决方案。但是,当我尝试它时,由于以下错误而失败:convert-im6.q16: not authorized
foobar.pdf'`。显然,这是一个安全问题,可以通过这个线程解决 - askubuntu.com/questions/1081895/…【参考方案6】:
将第一个想法与他们的回复混合在一起,我认为这段代码可能令人满意
jpgs2pdf.sh
#!/bin/bash
cd $1
FILES=$( find . -type f -name "*jpg" | cut -d/ -f 2)
mkdir temp > /dev/null
cd temp
for file in $FILES; do
BASE=$(echo $file | sed 's/.jpg//g');
convert ../$BASE.jpg $BASE.pdf;
done &&
pdftk `ls -v *pdf` cat output ../`basename $1`.pdf
cd ..
rm -rf temp
【讨论】:
【参考方案7】:这就是我的做法: 第一行使用转换命令将所有 jpg 文件转换为 pdf。 第二行是将所有 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"`
【讨论】:
【参考方案8】:问题是因为你的 shell 是按照纯字母顺序扩展通配符,并且由于数字的长度不同,所以顺序会不正确:
$ echo *.jpg
1.jpg 10.jpg 100.jpg 101.jpg 102.jpg ...
解决方案是根据需要用零填充文件名,以便在运行转换命令之前它们的长度相同:
$ for i in *.jpg; do num=`expr match "$i" '\([0-9]\+\).*'`;
> padded=`printf "%03d" $num`; mv -v "$i" "$i/$num/$padded"; done
现在文件将按照正确的顺序通过通配符匹配,为转换命令做好准备:
$ echo *.jpg
001.jpg 002.jpg 003.jpg 004.jpg 005.jpg 006.jpg 007.jpg 008.jpg ...
【讨论】:
我用您的代码创建了一个sh
文件。但它在运行时显示以下错误:rename.sh: 2: rename.sh: Bad substitution
你在使用 bash 吗?如果有,是哪个版本?
GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
你是如何执行脚本的?使用source
或.
,还是使用shebang 线?您是否尝试过直接在交互式 shell 中直接执行代码?
sh
几乎总是与bash
不同。它通常是普通的 Bourne shell,或在特殊的 Bourne 仿真模式下运行的 bash
。无论哪种方式,sh
的语法有时会完全不同。我建议改用bash rename.sh
。以上是关于在 Linux 中将多个 jpg 合并为单个 pdf的主要内容,如果未能解决你的问题,请参考以下文章