是否有任何实用的方法可以使用Python从图像文件列表创建PDF?
在Perl中,我知道that module。有了它,我可以只用3行创建一个PDF:
use PDF::FromImage;
...
my $pdf = PDF::FromImage->new;
$pdf->load_images(@allPagesDir);
$pdf->write_file($bookName . '.pdf');
我需要做一些与此类似的事情,但是在Python中。我知道pyPdf模块,但我想要一些简单的东西。
@Edit
如果您通过Google访问,请输入以下代码:
from fpdf import FPDF
from PIL import Image
def makePdf(pdfFileName, listPages, dir = ''):
if (dir):
dir += "/"
cover = Image.open(dir + str(listPages[0]) + ".jpg")
width, height = cover.size
pdf = FPDF(unit = "pt", format = [width, height])
for page in listPages:
pdf.add_page()
pdf.image(dir + str(page) + ".jpg", 0, 0)
pdf.output(dir + pdfFileName + ".pdf", "F")
答案 0 :(得分:43)
pip install fpdf
现在你可以使用相同的逻辑:
from fpdf import FPDF
pdf = FPDF()
# imagelist is the list with all image filenames
for image in imagelist:
pdf.add_page()
pdf.image(image,x,y,w,h)
pdf.output("yourfile.pdf", "F")
您可以找到更多信息at the tutorial page或official documentation。
答案 1 :(得分:19)
如果使用Python 3,则可以使用python模块img2pdf
使用pip3 install img2pdf
安装它,然后您可以在脚本中使用它
使用import img2pdf
示例代码
import os
import img2pdf
with open("output.pdf", "wb") as f:
f.write(img2pdf.convert([i for i in os.listdir('path/to/imageDir') if i.endswith(".jpg")]))
答案 2 :(得分:14)
将多个图像转换为PDF的最佳方法我到目前为止尝试过纯粹使用PIL
。它非常简单但功能强大:
from PIL import Image
im1 = Image.open("/Users/apple/Desktop/bbd.jpg")
im2 = Image.open("/Users/apple/Desktop/bbd1.jpg")
im3 = Image.open("/Users/apple/Desktop/bbd2.jpg")
im_list = [im2,im3]
pdf1_filename = "/Users/apple/Desktop/bbd1.pdf"
im1.save(pdf1_filename, "PDF" ,resolution=100.0, save_all=True, append_images=im_list)
只需将save_all
设置为True
,将append_images
设置为您要添加的图片列表。
您可能会遇到AttributeError: 'JpegImageFile' object has no attribute 'encoderinfo'
。解决方案在Error while saving multiple JPEGs as a multi-page PDF
注意:安装最新的PIL
以确保save_all
参数可用于PDF。
答案 3 :(得分:3)
pgmagick是Python的GraphicsMagick(Magick++)
绑定。
它是ImageMagick(或GraphicsMagick)的Python包装器。
import os
from os import listdir
from os.path import isfile, join
from pgmagick import Image
mypath = "\Images" # path to your Image directory
for each_file in listdir(mypath):
if isfile(join(mypath,each_file)):
image_path = os.path.join(mypath,each_file)
pdf_path = os.path.join(mypath,each_file.rsplit('.', 1)[0]+'.pdf')
img = Image(image_path)
img.write(pdf_path)
Sample input Image:
PDF looks like this:
用于windows的pgmagick iinstallation指令:
1)从Unofficial Windows Binaries for Python Extension Packages下载预编译的二进制包(如pgmagick网页中所述)并安装它。
注意: 尝试下载与您机器中安装的python版本对应的正确版本,无论是32位安装还是64位。
只需在终端输入python并按Enter即可检查是否有32位或64位python。
D:\>python
ActivePython 2.7.2.5 (ActiveState Software Inc.) based on
Python 2.7.2 (default, Jun 24 2011, 12:21:10) [MSC v.1500 32 bit (Intel)] on win32
Type "help", "copyright", "credits" or "license" for more information.
因此它有python version 2.7
及其32 bit (Intel)] on win32
所以你必须下载并安装pgmagick‑0.5.8.win32‑py2.7.exe
。
以下是pgmagick的可用Python扩展包:
2)然后您可以按照here的安装说明进行操作。
pip install pgmagick
然后尝试导入它。
>>> from pgmagick import gminfo
>>> gminfo.version
'1.3.x'
>>> gminfo.library
'GraphicsMagick'
>>>
答案 4 :(得分:3)
这个怎么样?
from fpdf import FPDF
from PIL import Image
import glob
import os
# set here
image_directory = '/path/to/imageDir'
extensions = ('*.jpg','*.png','*.gif') #add your image extentions
# set 0 if you want to fit pdf to image
# unit : pt
margin = 10
imagelist=[]
for ext in extensions:
imagelist.extend(glob.glob(os.path.join(image_directory,ext)))
for imagePath in imagelist:
cover = Image.open(imagePath)
width, height = cover.size
pdf = FPDF(unit="pt", format=[width + 2*margin, height + 2*margin])
pdf.add_page()
pdf.image(imagePath, margin, margin)
destination = os.path.splitext(imagePath)[0]
pdf.output(destination + ".pdf", "F")
答案 5 :(得分:2)
命令行界面中的第一个pip install pillow
。
图片可以是jpg或png格式。如果您有2张或更多图片,并且想要制作1张pdf文件。
代码:
from PIL import Image
image1 = Image.open(r'locationOfImage1\\Image1.png')
image2 = Image.open(r'locationOfImage2\\Image2.png')
image3 = Image.open(r'locationOfImage3\\Image3.png')
im1 = image1.convert('RGB')
im2 = image2.convert('RGB')
im3 = image3.convert('RGB')
imagelist = [im2,im3]
im1.save(r'locationWherePDFWillBeSaved\\CombinedPDF.pdf',save_all=True, append_images=imagelist)
答案 6 :(得分:2)
**** Convert images files to pdf file.****
from os import listdir
from fpdf import FPDF
path = "/home/bunny/images/" # get the path of images
imagelist = listdir(path) # get list of all images
pdf = FPDF('P','mm','A4') # create an A4-size pdf document
x,y,w,h = 0,0,200,250
for image in imagelist:
pdf.add_page()
pdf.image(path+image,x,y,w,h)
pdf.output("images.pdf","F")
答案 7 :(得分:2)
如果图像是您通过matplotlib创建的图,则可以使用matplotlib.backends.backend_pdf.PdfPages
(See documentation)。
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
# generate a list with dummy plots
figs = []
for i in [-1, 1]:
fig = plt.figure()
plt.plot([1, 2, 3], [i*1, i*2, i*3])
figs.append(fig)
# gerate a multipage pdf:
with PdfPages('multipage_pdf.pdf') as pdf:
for fig in figs:
pdf.savefig(fig)
plt.close()
答案 8 :(得分:1)
您可以使用 pdfme。是python中创建PDF文档最强大的库。
from pdfme import build_pdf
...
pdf_image_list = [{"image": img} for img in images]
with open('images.pdf', 'wb') as f:
build_pdf({"sections": [{"content": pdf_image_list}]})
检查文档 here
答案 9 :(得分:1)
这是ilovecomputer的答案,打包成一个函数,可以直接使用。它还可以减小图像尺寸,并且效果很好。
该代码假定input_dir中有一个文件夹,其中包含按图像名称按字母顺序排序的图像,并输出带有该文件夹名称的pdf文件,并可能以该名称为前缀字符串。
import os
from PIL import Image
def convert_images_to_pdf(export_dir, input_dir, folder, prefix='', quality=20):
current_dir = os.path.join(input_dir, folder)
image_files = os.listdir(current_dir)
im_list = [Image.open(os.path.join(current_dir, image_file)) for image_file in image_files]
pdf_filename = os.path.join(export_dir, prefix + folder + '.pdf')
im_list[0].save(pdf_filename, "PDF", quality=quality, optimize=True, save_all=True, append_images=im_list[1:])
export_dir = r"D:\pdfs"
input_dir = r"D:\image_folders"
folders = os.listdir(input_dir)
[convert_images_to_pdf(export_dir, input_dir, folder, prefix='') for folder in folders];
答案 10 :(得分:1)
我知道这个问题已经得到解答,但解决这个问题的另一种方法是使用枕头库。 要转换整个图像目录:
from PIL import Image
import os
def makePdf(imageDir, SaveToDir):
'''
imageDir: Directory of your images
SaveToDir: Location Directory for your pdfs
'''
os.chdir(imageDir)
try:
for j in os.listdir(os.getcwd()):
os.chdir(imageDir)
fname, fext = os.path.splitext(j)
newfilename = fname + ".pdf"
im = Image.open(fname + fext)
if im.mode == "RGBA":
im = im.convert("RGB")
os.chdir(SaveToDir)
if not os.path.exists(newfilename):
im.save(newfilename, "PDF", resolution=100.0)
except Exception as e:
print(e)
imageDir = r'____' # your imagedirectory path
SaveToDir = r'____' # diretory in which you want to save the pdfs
makePdf(imageDir, SaveToDir)
在单张图片上使用它:
From PIL import Image
import os
filename = r"/Desktop/document/dog.png"
im = Image.open(filename)
if im.mode == "RGBA":
im = im.convert("RGB")
new_filename = r"/Desktop/document/dog.pdf"
if not os.path.exists(new_filename):
im.save(new_filename,"PDF",resolution=100.0)
答案 11 :(得分:0)
这不是一个真正的新答案,但是-使用img2pdf时,页面大小显示不正确。所以这是我使用图像尺寸的方法,希望它能找到合适的人:
假设1)所有图像的尺寸相同,2)每页放置一张图像,3)图像充满整个页面
from PIL import Image
import img2pdf
with open( 'output.pdf', 'wb' ) as f:
img = Image.open( '1.jpg' )
my_layout_fun = img2pdf.get_layout_fun(
pagesize = ( img2pdf.px_to_pt( img.width, 96 ), img2pdf.px_to_pt( img.height, 96 ) ), # this is where image size is used; 96 is dpi value
fit = img2pdf.FitMode.into # I didn't have to specify this, but just in case...
)
f.write( img2pdf.convert( [ '1.jpg', '2.jpg', '3.jpg' ], layout_fun = my_layout_fun ))
答案 12 :(得分:0)
最佳答案已经存在!!!我只是在稍微改善答案。 这是代码:
from fpdf import FPDF
pdf = FPDF()
# imagelist is the list with all image filenames you can create using os module by iterating all the files in a folder or by specifying their name
for image in imagelist:
pdf.add_page()
pdf.image(image,x=0,y=0,w=210,h=297) # for A4 size because some people said that every other page is blank
pdf.output("yourfile.pdf", "F")
为此,您需要安装FPDF。
pip install FPDF
答案 13 :(得分:0)
受@ilovecomputer的回答启发,现成的解决方案可将当前文件夹中的所有PNG转换为PDF。
import glob, PIL.Image
L = [PIL.Image.open(f) for f in glob.glob('*.png')]
L[0].save('out.pdf', "PDF" ,resolution=100.0, save_all=True, append_images=L[1:])
除了PIL之外,什么都不需要:)
答案 14 :(得分:0)
如果图像处于横向模式,则可以这样做。
from fpdf import FPDF
import os, sys, glob
from tqdm import tqdm
pdf = FPDF('L', 'mm', 'A4')
im_width = 1920
im_height = 1080
aspect_ratio = im_height/im_width
page_width = 297
# page_height = aspect_ratio * page_width
page_height = 200
left_margin = 0
right_margin = 0
# imagelist is the list with all image filenames
for image in tqdm(sorted(glob.glob('test_images/*.png'))):
pdf.add_page()
pdf.image(image, left_margin, right_margin, page_width, page_height)
pdf.output("mypdf.pdf", "F")
print('Conversion completed!')
这里的page_width和page_height是'A4'纸的尺寸,在横向中其宽度为297mm,高度为210mm;但是在这里我已经根据我的图像调整了高度。或者,您可以使用保持上面所述的高宽比来适当缩放图像的宽度和高度。
答案 15 :(得分:0)
我遇到了同样的问题,所以我创建了一个python函数来将多个图片合并为一个pdf。该代码(可从my github page获取,使用reportlab
,并基于以下链接的答案:
以下是如何将图像合并为pdf的示例:
我们有文件夹“D:\ pictures”和png和jpg类型的图片,我们想要创建文件pdf_with_pictures.pdf并保存在同一个文件夹中。
outputPdfName = "pdf_with_pictures"
pathToSavePdfTo = "D:\\pictures"
pathToPictures = "D:\\pictures"
splitType = "none"
numberOfEntitiesInOnePdf = 1
listWithImagesExtensions = ["png", "jpg"]
picturesAreInRootFolder = True
nameOfPart = "volume"
unite_pictures_into_pdf(outputPdfName, pathToSavePdfTo, pathToPictures, splitType, numberOfEntitiesInOnePdf, listWithImagesExtensions, picturesAreInRootFolder, nameOfPart)
答案 16 :(得分:0)
我知道这是一个老问题。就我而言,我使用Reportlab。
纸页尺寸以点而不是像素表示,其点等于1/72英寸。 A4纸由595.2点宽和841.8点高组成。位置坐标(0,0)的原点在左下角。创建canvas.Canvas实例时,可以使用pagesize参数指定图纸的大小,并传递一个元组,其第一个元素表示以磅为单位的宽度,第二个元素表示以磅为单位的高度。 c.showPage()方法告诉ReportLab它已经完成了对当前工作表的处理,并移至下一个工作表。尽管尚未处理第二张纸(只要未绘制任何内容,第二张纸就不会出现在文档中),但最好记住在调用c.save()之前先这样做。要将图像插入PDF文档中,ReportLab使用Pillow库。 drawImage()方法将图像的路径(支持多种格式,例如PNG,JPEG和GIF)和要插入的位置(x,y)作为其参数。可以通过width和height参数来缩小或放大图像以指示其尺寸。
以下代码提供了pdf文件名,带有png文件的列表,用于插入图像的坐标以及适合纵向字母页面的大小。
def pntopd(file, figs, x, y, wi, he):
from reportlab.pdfgen import canvas
from reportlab.lib.pagesizes import A4, letter, landscape, portrait
w, h = letter
c = canvas.Canvas(str(file), pagesize=portrait(letter))
for png in figs:
c.drawImage(png, x, h - y, width=wi, height=he)
c.showPage()
c.save()
from datetime import date
from pathlib import Path
ruta = "C:/SQLite"
today = date.today()
dat_dir = Path(ruta)
tit = today.strftime("%y%m%d") + '_ParameterAudit'
pdf_file = tit + ".pdf"
pdf_path = dat_dir / pdf_file
pnglist = ['C0.png', 'C4387.png', 'C9712.png', 'C9685.png', 'C4364.png']
pntopd(pdf_path, pnglist, 50, 550, 500, 500)
答案 17 :(得分:0)
在python 3.7和img2pdf 0.4.0版中对我有用的是使用类似于Syed Shamikh Shabbir给出的代码的东西,但是按照Stu在对Syed解决方案的评论中建议的那样,使用OS更改当前工作目录
import os
import img2pdf
path = './path/to/folder'
os.chdir(path)
images = [i for i in os.listdir(os.getcwd()) if i.endswith(".jpg")]
for image in images:
with open(image[:-4] + ".pdf", "wb") as f:
f.write(img2pdf.convert(image))
值得一提的是,上述解决方案将每个.jpg文件分别保存为一个pdf文件。如果您只希望将所有.jpg文件集中在一个.pdf文件中,则可以执行以下操作:
import os
import img2pdf
path = './path/to/folder'
os.chdir(path)
images = [i for i in os.listdir(os.getcwd()) if i.endswith(".jpg")]
with open("output.pdf", "wb") as f:
f.write(img2pdf.convert(images))
答案 18 :(得分:0)
我接受了代码并进行了一些细微的改动,使其可用。
from fpdf import FPDF
from PIL import Image
import os # I added this and the code at the end
def makePdf(pdfFileName, listPages, dir=''):
if (dir):
dir += "/"
cover = Image.open(dir + str(listPages[0]))
width, height = cover.size
pdf = FPDF(unit="pt", format=[width, height])
for page in listPages:
pdf.add_page()
pdf.image(dir + str(page), 0, 0)
pdf.output(dir + pdfFileName + ".pdf", "F")
# this is what I added
x = [f for f in os.listdir() if f.endswith(".jpg")]
y = len(x)
makePdf("file", x)