在 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.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。

【问题讨论】:

代表用户 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的主要内容,如果未能解决你的问题,请参考以下文章

如何在git中将大型合并请求拆分为多个部分

在vba中将单个png文件转换为jpg

在 pandas/python 的同一数据框中将两列合并为一列

如何在单个表中将多行合并为 1 行 [重复]

excel中将两个单元格的内容合并

如何在oracle中将两个更新查询合并为单个更新查询?