在Linux中将多个jpg合并为单个pdf


73

我使用以下命令将jpg目录中的所有文件转换并合并为单个pdf文件。

convert *.jpg file.pdf

目录中的文件从编号1.jpg123.jpg。转换进行得很好,但转换后页面都混合了。我希望pdf的页面从1.jpg123.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。


2
代表用户sindhus添加注释,该用户没有足够的注释点(请参见下文):该convert命令是imagemagick软件包的一部分。
Teemu Leisti

1
错误:convert-im6.q16:尝试执行安全策略“ PDF”不允许的操作
Max N

如果您遇到安全政策问题,请访问:askubuntu.com/a/1081907/281163
Max N

Answers:


19

问题是因为您的外壳按纯字母顺序扩展了通配符,并且由于数字的长度不同,所以顺序将是错误的:

$ 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 ...

我已经sh用您的代码创建了一个文件。但是它在运行时显示以下错误:rename.sh: 2: rename.sh: Bad substitution
Harikrishnan 2012年

您正在使用bash吗?如果是这样,哪个版本?
Delan Azabani 2012年

GNU bash, version 4.2.24(1)-release (i686-pc-linux-gnu)
Harikrishnan

您如何执行脚本?使用source.,还是使用shebang行?您是否尝试过直接在交互式shell中直接执行代码?
Delan Azabani 2012年

1
sh几乎和bash。通常是纯Bourne外壳,或bash以特殊的Bourne仿真模式运行。无论哪种方式,sh有时的语法都可能完全不同。我建议bash rename.sh改用。
Delan Azabani 2012年

115

或只是阅读ls手册并参阅:

-v文本中自然的(版本)数字排序

因此,在单个命令中执行我们需要的操作。

convert `ls -v *.jpg` foobar.pdf

玩得开心;)F.


1
@Jason:可以(+1)。但是您是否最终忘记了大多数数码相机将图像存储为*.JPG和不是*.jpg
马丁·托马

1
当文件名中有空格时失败,除非拇指向上!:))
ablacksheep

3
注意,这是GNU ls的功能,而不是BSD ls的功能。安装GNU的coreutils获得GNU LS在BSD家族和OS X.
4ae1e1

3
如果您按顺序生成图像,则另一个好方法是按带有ls -t标志的修改时间进行排序。同样,该-r标志颠倒顺序。
spelufo

5
这是一个很好的解决方案。但是,当我尝试它时,由于以下错误而失败:convert-im6.q16: not authorized foob​​ar.pdf'`。显然,这是一个安全问题,可以通过此线程解决-askubuntu.com/questions/1081895/…–
Scott

4

这是我的方法:
第一行将所有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"`

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


3

当我想合并许多高分辨率的jpeg图像(来自扫描的书)时,上述所有答案对我来说都是失败的。

Imagemagick尝试将所有文​​件加载到RAM中,因此我使用了以下两步方法:

find -iname "*.JPG" | xargs -I'{}' convert {} {}.pdf
pdfunite *.pdf merged_file.pdf

请注意,通过这种方法,您还可以使用GNU parallel来加快转换速度:

find -iname "*.JPG" | parallel -I'{}' convert {} {}.pdf

0

我将他们的回答与第一个想法混在一起,我认为这段代码可能令人满意

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
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.