programing

이미지 목록에서 PDF 만들기

coolbiz 2023. 7. 29. 13:01
반응형

이미지 목록에서 PDF 만들기

파이썬을 사용하여 이미지 파일 목록에서 PDF를 만드는 실용적인 방법이 있습니까?

Perl에서 는 그 모듈을 알고 있습니다.이 기능을 사용하면 PDF를 세 줄로 만들 수 있습니다.

use PDF::FromImage;
...
my $pdf = PDF::FromImage->new;
$pdf->load_images(@allPagesDir);
$pdf->write_file($bookName . '.pdf');

저는 이것과 매우 유사한 것을 해야 하지만, 파이썬에서.는 pyPdf 모듈을 알고 있지만 간단한 것을 원합니다.

한 여러 은 여러이로를미지다것변입사니가방용는좋하법은은장환는하▁the▁to▁to▁i다▁use것▁to입니를 사용하는 것입니다.PIL강력합니다매우 간단하면서도 강력합니다.

from PIL import Image  # install by > python3 -m pip install --upgrade Pillow  # ref. https://pillow.readthedocs.io/en/latest/installation.html#basic-installation

images = [
    Image.open("/Users/apple/Desktop/" + f)
    for f in ["bbd.jpg", "bbd1.jpg", "bbd2.jpg"]
]

pdf_path = "/Users/apple/Desktop/bbd1.pdf"
    
images[0].save(
    pdf_path, "PDF" ,resolution=100.0, save_all=True, append_images=images[1:]
)

설하기정으로 설정하세요.save_allTrue그리고.append_images추가할 이미지 목록에 추가합니다.

다음과 같은 상황이 발생할 수 있습니다.AttributeError: 'JpegImageFile' object has no attribute 'encoderinfo'여러 JPEG를 다중 페이지 PDF로 저장하는 동안 오류가 발생했습니다.

버전 설치: PIL 하기 save_allPDF에 인수를 사용할 수 있습니다.

추신.

이 오류가 발생할 경우

모드 RGBA를 저장할 수 없습니다.

수정을 적용합니다.

png = Image.open('/path/to/your/file.png')
png.load()
background = Image.new("RGB", png.size, (255, 255, 255))
background.paste(png, mask=png.split()[3]) # 3 is the alpha channel

Python용 FPDF 설치:

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")

자세한 내용은 튜토리얼 페이지 또는 공식 설명서에서 확인할 수 있습니다.

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")]))

또는 (경로 문제로 인해 이전 접근 방식에서 오류가 발생한 경우)

# convert all files matching a glob
import glob
with open("name.pdf","wb") as f:
    f.write(img2pdf.convert(glob.glob("/path/to/*.jpg")))

이면 mithmatplotlib을 할 수 .matplotlib.backends.backend_pdf.PdfPages(설명서 참조).

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()

pgmagick은GraphicsMagick(Magick++)Python에 대한 바인딩입니다.

이것은 ImageMagick(또는 GraphicsMagick)용 파이썬 래퍼입니다.

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:

enter image description here

PDF looks like this:

enter image description here

윈도우용 pgmagicki 설치 지침:

pgmagick 웹 페이지에서 언급한 대로 Python 확장 패키지용 비공식 윈도우즈 바이너리에서 사전 컴파일된 이진 패키지를 다운로드하여 설치합니다.

참고: 컴퓨터에 설치된 파이썬 버전과 32비트 설치인지 64비트인지에 해당하는 올바른 버전을 다운로드하십시오.

단말기에 python을 입력하고 Enter를 누르면 32bit python이 있는지 64bit 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 확장 패키지입니다.

  • pgmagick - 0.5.8.win-44064 -py2.6.exe
  • pgmagick - 0.5.8.win-44064 -py2.7.exe
  • pgmagick - 0.5.8.win-44064 -py3.2.exe
  • pgmagick - 0.5.8.win32 - py2.6.exe
  • pgmagick - 0.5.8.win32 - py2.7.exe
  • pgmagick - 0.5.8.win32 - py3.2.exe

그러면 당신은 여기서 설치 지침을 따를 수 있습니다.

pip install pgmagick

그런 다음 가져오기를 시도합니다.

>>> from pgmagick import gminfo
>>> gminfo.version
'1.3.x'
>>> gminfo.library
'GraphicsMagick'
>>>
**** 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")

번째pip install pillow명령행 인터페이스에 있습니다.의 pdf파일로 에는 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)

파일이 있는 dir에서 pdf를 만들기 위한 몇 가지 변경 사항

저는 코드를 가져다가 그대로 사용할 수 있도록 약간의 변경을 했습니다.

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)

이것은 어떻습니까?

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")

질문에 대한 답이 나왔다는 것을 알지만, 이것을 해결하기 위한 또 다른 방법은 베개 라이브러리를 사용하는 것입니다.전체 이미지 디렉토리를 변환하는 방법

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)

정말 새로운 답변은 아니지만, 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 ))

여기 아이러브 컴퓨터의 답이 함수에 포함되어 있고 직접 사용할 수 있습니다.또한 이미지 크기를 줄일 수 있고 잘 작동합니다.

코드는 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];

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))

저의 경우 100개 이상의 이미지를 서로 다른 형식(알파 채널 유무 및 다른 확장자)으로 변환해야 했습니다.

저는 이 질문에 대한 답에서 모든 수용체를 시도했습니다.

필 =>은 알파 채널과 함께 또는 없이 결합할 수 없습니다(이미지를 변환해야 함).

fpdf => 많은 이미지에 스택

html ingotenberg에서 인쇄 => 매우 긴 처리.

그리고 제 마지막 시도는 보고서 연구소였습니다.그리고 그것은 멋지고 빠르게 작동합니다. (그러나 때때로 큰 입력에서 손상된 PDF를 생성합니다.)여기 제 코드가 있습니다.

from PyPDF2 import PdfMerger
from reportlab.lib.pagesizes import letter
from reportlab.lib.units import inch
from reportlab.platypus import Image, PageBreak, Paragraph, SimpleDocTemplate

async def save_report_lab_story_to_pdf(file_name, story):
    doc = SimpleDocTemplate(
        file_name,
        pagesize=letter,
        rightMargin=32,
        leftMargin=32,
        topMargin=18,
        bottomMargin=18,
    )
    doc.build(story)


async def reportlab_pdf_builder(data, images):
    story = []
    width = 7.5 * inch
    height = 9 * inch

    chunk_size = 5 * 70
    pdf_chunks = []

    files_to_clean_up = []
    for trip in data['trips']:
        for invoice in trip['invoices']:
            for page in invoice['pages']:
                if trip['trip_label']:
                    story.append(Paragraph(
                        f"TRIP: {trip['trip_label']} {trip['trip_begin']} - {trip['trip_end']}"
                    ))
                else:
                    story.append(Paragraph("No trip"))

                story.append(Paragraph(
                    f"""Document number: {invoice['invoice_number']}
                        Document date: {invoice['document_date']}
                        Amount: {invoice['invoice_trip_value']} {invoice['currency_code']}
                    """
                ))
                story.append(Paragraph(" "))
                img_name = page['filename']
                img_bytes = images[page['path']]
                tmp_img_filename = f'/tmp/{uuid.uuid4()}.{img_name}'
                with open(tmp_img_filename, "wb") as tmp_img:
                    tmp_img.write(img_bytes)
                im = Image(tmp_img_filename, width, height)
                story.append(im)
                story.append(PageBreak())
                files_to_clean_up.append(tmp_img_filename)
                # 5 objects per page in story

                if len(story) >= chunk_size:
                    file_name = f"/tmp/{uuid.uuid4()}_{data['tail_number']}.pdf"
                    await save_report_lab_story_to_pdf(file_name, story)
                    story = []
                    pdf_chunks.append(file_name)

    merger = PdfMerger()
    for pdf in pdf_chunks:
        merger.append(pdf)

    res_file_name = f"/tmp/{uuid.uuid4()}_{data['tail_number']}.pdf"
    merger.write(res_file_name)
    merger.close()

저도 같은 문제가 있어서 파이썬 함수를 만들어서 여러 사진을 하나의 pdf로 통합했습니다.코드(내 github 페이지에서 사용 가능, 사용)reportlab다음 링크의 답변을 기반으로 합니다.

다음은 이미지를 PDF로 통합하는 방법의 예입니다.

png 및 jpg 유형의 사진이 있는 "D:\pictures" 폴더가 있으며, 이 폴더에서 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)

@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 외에 다른 것은 필요하지 않습니다 :)

이미지가 가로 모드인 경우 이렇게 할 수 있습니다.

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는 가로 297mm, 세로 210mm의 'A4' 용지 크기입니다. 하지만 여기서는 이미지에 따라 높이를 조정했습니다.또는 위에서 언급한 대로 가로 세로 비율을 유지하여 이미지의 너비와 높이를 적절히 조정할 수 있습니다.

이것이 오래된 질문이라는 것을 압니다.제 경우에는 Reportlab을 사용합니다.

시트 치수는 1/72인치와 동일한 점으로 픽셀이 아닌 점으로 표시됩니다.A4 시트는 폭 595.2 포인트와 높이 841.8 포인트로 구성되어 있습니다.위치 좌표(0, 0)의 원점은 왼쪽 하단 모서리에 있습니다.캔버스 인스턴스를 만들 때입니다.캔버스에서 페이지 크기 매개변수를 사용하여 첫 번째 요소가 점의 너비를 나타내는 튜플을 전달하고 두 번째 요소인 높이를 지정할 수 있습니다.c.showPage() 메서드는 ReportLab에 현재 시트에 대한 작업이 이미 완료되었음을 알려주고 다음 시트로 이동합니다.아직 두 번째 시트에 대한 작업이 수행되지 않았지만(그리고 아무것도 그려지지 않은 한 문서에 나타나지 않을 것), c.save()를 호출하기 전에 이 작업을 수행하는 것이 좋습니다.PDF 문서에 이미지를 삽입하기 위해 ReportLab은 Pillow 라이브러리를 사용합니다.drawImage() 메서드는 이미지의 경로(PNG, JPEG 및 GIF와 같은 여러 형식 지원)와 삽입할 위치(x, y)를 인수로 사용합니다.이미지는 너비 및 높이 인수를 통해 크기를 표시하여 축소하거나 확대할 수 있습니다.

다음 코드는 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)

당신은 pdf me를 사용할 수 있습니다.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}]})

여기에서 문서를 확인

최고의 답은 이미 존재합니다!!!저는 단지 답을 조금 개선하고 있을 뿐입니다.코드는 다음과 같습니다.

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

@ilovecomputer의 답변에 추가하여 PDF를 디스크가 아닌 메모리에 저장하려면 다음을 수행할 수 있습니다.

import io
from pdf2image import convert_from_bytes
 
pil_images = convert_from_bytes(original_pdf_bytes, dpi=100) # (OPTIONAL) do this if you're converting a normal pdf to images first and then back to only image pdf
pdf_output = io.BytesIO()
pil_images[0].save(pdf_output, "PDF", resolution=100.0, save_all=True, append_images=pil_images[1:])
pdf_bytes = pdf_output.getvalue()

답변은 합법적인 것 같았지만 "str이 아니라 바이트와 유사한 개체가 필요합니다"라는 오류로 인해 작동할 수 없었습니다.img2pdf 설명서를 읽은 후, 다음과 같이 작업했습니다.

import img2pdf
import os

dirname = "/path/to/images"
imgs = []
for fname in os.listdir(dirname):
    if not fname.endswith(".jpg") and not fname.endswith(".png"):
        continue
    path = os.path.join(dirname, fname)
    if os.path.isdir(path):
        continue
    imgs.append(path)
with open("name.pdf","wb") as f:
    f.write(img2pdf.convert(imgs))

언급URL : https://stackoverflow.com/questions/27327513/create-pdf-from-a-list-of-images

반응형