DEV Community

Cover image for Crafting an Image to PDF Converter App Using Python.
Ebikara Spiff
Ebikara Spiff

Posted on • Edited on

Crafting an Image to PDF Converter App Using Python.

Have you ever found yourself in a situation where you needed to convert a bunch of images into a PDF file quickly and efficiently? Imagine the convenience of converting a series of images from your recent trip into a single PDF album with just a few clicks. In this article, we will cover the process of building an Image PDF Converter App using Python. With the help of libraries like tkinter, os, and Python Imaging Library (PIL), we'll walk through the process of creating a powerful tool that can streamline this task for you.

Throughout this tutorial, we will explore the step-by-step process of developing a user-friendly application that not only converts images to PDF but also allows for customization and optimization. By the end of this article, you will have a solid understanding of how to leverage these Python libraries to create a practical solution to your image conversion needs.

Setting Up The Project Environment

When working in Visual Studio Code (VS Code), start by creating a new Python file for our image-to-PDF project. It's helpful to have separate files for different parts of your project.

Create a new Python application:

To do this, you can start by opening your VS Code and creating a new folder:

Step 1

Open VS Code

vs code main page

Step 2

Create new folder

create new folder in VS code

Step 3

Head over to the newly created folder and create a new file called app.py.

New Python file

Install libraries

To start we are going to install Python libraries Tkinter, Python Imaging Library (PIL):



pip install tk pillow


Enter fullscreen mode Exit fullscreen mode

Installing tk and pillow

Next, we import our libraries:



import tkinter as tk
from tkinter import filedialog
from reportlab.pdfgen import canvas
from PIL import image
import OS


Enter fullscreen mode Exit fullscreen mode

Creating Class

A class contains the image loading and PDF conversion functionality, making it easier to manage the overall conversion process.

Step 1

To get started first, we will create a class ImagetoPDFConverter:



class ImageToPDFConverter


Enter fullscreen mode Exit fullscreen mode

Step 2

Next, we have to initialize our self and root:



   def__init__(self,root):


Enter fullscreen mode Exit fullscreen mode

To initialize, we will call self:



self.root=root


Enter fullscreen mode Exit fullscreen mode

After initializing our roots, we will create some important variables.

Step 3

First, we create variables for our images:



self.image_paths = [ ]


Enter fullscreen mode Exit fullscreen mode

We are leaving self.image_paths empty because we are going to convert multiple images to PDF files.

Step 4

To convert our images to PDF, we have to create a variable for PDF:



self.output_pdf_name = tk.StrngVar( ) 


Enter fullscreen mode Exit fullscreen mode

Step 5

When we select multiple images to convert to PDF, we need to create a variable to store the names of the images:



self.selected_images_listbox = tk.Listbox(root, selectmode=tk.MULTIPLE)


Enter fullscreen mode Exit fullscreen mode

Step 6

Next, we initialize the UI, and to do this we have to create an instance name:



self.initialize_ui()


Enter fullscreen mode Exit fullscreen mode

Step 7

We define our instance:



def initialize _ui(self):


Enter fullscreen mode Exit fullscreen mode

Now, we create variables and define our components like title buttons, our listing space, input section and our convert button.

Step 8

First, we are going to create a variable for our title image to PDF converter:



def initialize _ui(self):
   title_label = tk.Label(self.root, text ='image to pdf converter' , font =('Helvetica', 16, 'bold'))
   title_label.pack(pady=10)


Enter fullscreen mode Exit fullscreen mode

Step 9

To check if the components we just created above are working, we have to define our main:



def main():
root = tk.Tk()


Enter fullscreen mode Exit fullscreen mode

Step 10

Next, we create a title also for the window:



root.title("image to pdf")
Converter = ImageToPDFConverter(root)


Enter fullscreen mode Exit fullscreen mode

Step 11

Finally, we initialize the size for our window:



root.geometry("400x600")
root.mainloop()


Enter fullscreen mode Exit fullscreen mode


if__name__ == "__main__":
main()


Enter fullscreen mode Exit fullscreen mode

Step 12

Save and run our code

Image of main window

Design GUI for Application

Designing a GUI for an application refers to creating the graphical user interface (GUI) that users will interact with when using the application. It involves designing the layout, appearance, and functionality of the user interface elements.

Step 1

To get started, we create our select image button:



select_image_button= tk.Button(self.root, text ='select images', command = self.select_images)
select_image_button.pack(pady=(0,10))


Enter fullscreen mode Exit fullscreen mode

Step 2

Next, we create our list box.
To do this we first initialize our self and create a variable:



self.selected_images_listbox.pck(pady=(0,10), fill=tk.BOTH, expand=True)


Enter fullscreen mode Exit fullscreen mode

Step 3

Next, we will create a list label, to do this we have to create a variable label.:



label = tk.label(self.root,text="enter output pdf name")
label.pack()


Enter fullscreen mode Exit fullscreen mode

Step 4

We need an input section so users can type a personalized name for the generated PDF file:



pdf_name_entry = tk.Entry(self.root,textvariable=self.output_pdf_name, width=40, justify =='center')
pdf_name_entry.pack()


Enter fullscreen mode Exit fullscreen mode

Step 5

Next, we create our convert to pdf button:



convert_button= tk.Button(self.root, text ='convert to pdf ', command = self.convert_images_to_pdf)
convert_button.pack(pady=(20,40))


Enter fullscreen mode Exit fullscreen mode

Implementing Button Functions

When we click on the select image button, our file explorer should open for us to select some images and also save the names in the list box.

Step 1

To do this, first, we create a variable and call it self:



def select_images(self)
   self.image_paths = filedalog.askopenfilenames(title="select images", filetypes = [('images files', '*.png;*.jpg;*.jpeg)])
 self.update_selected_images_listbox()


Enter fullscreen mode Exit fullscreen mode

(* represents the file name and the file names that we select could be anything, so we use * )

Step 2

After selecting our images we want to update our image on the list box:



def update_selected_images_listbox(self):
   self.selected_images_listbox.delete(0,tk.END)


Enter fullscreen mode Exit fullscreen mode

Step 3

Next, let's find out if there are any names already on the list. If we come across any, we'll remove them and then split them up.

This is useful when you want to display only the file names in a user interface component like a list box, without showing the entire file path:



for image_path in self.image_paths:
      _, image_path = os.path.split(image_path)
self.selected_images_lisbox.insert(tk.End,image_path)


Enter fullscreen mode Exit fullscreen mode

Convert Images into PDF Function

We need to prompt the user to input a personalized name to save the PDF file. If the user fails to provide a name, we can automatically generate one.

Step 1

To do this we need to define convert_images_to_pdf:



def convert_images_to_pdf(self):
     if not self.image_paths:
       return
    output_pdf_path = self.output_pdf_name.get() + ".pdf" if self.output_pdf_name.get()
    else "output.pdf"


Enter fullscreen mode Exit fullscreen mode

Inserting images into PDF pages

After deciding on the PDF name, we initialize a page size for the PDF.

The standard PDF page size is 612 by 792,

Step 1

To do this we create a variable pdf:



pdf = canvas.canvas(output_pdf_path, pagesize = (612,792))


Enter fullscreen mode Exit fullscreen mode

Step 2

Continuing with the process, we will iterate through each image file path and open the corresponding image using the PIL library. This way, we can assign each opened image to the variable img one by one:



for image_path in self.image_paths:
    img = image.open(image_path)


Enter fullscreen mode Exit fullscreen mode

Step 3

For placing all images in the center of our PDF page, we will create a variable 'scale_factor':



for image_path in self.image_paths:
    img = image.open(image_path)
    available_width =540
    available_height = 720
    scalefactor = min(available_width/ img.width, available_height/img.height)
    new_width = img.width * scale_factor
    new_height = img.height* scale_factor


Enter fullscreen mode Exit fullscreen mode

Step 4

Next, we have to determine the x and y values:



x_centered =(612 - new_width)/2
y_centered =(792 - new_height)/2


Enter fullscreen mode Exit fullscreen mode

Step 5

Next, we also want to add a white margin color:



pdf.setFilColorRGB(255,255,255)
pdf.rect(0,0,612,792,fill=True)


Enter fullscreen mode Exit fullscreen mode

Step 6

Next, we want to add the image at the center of our white page:



pdfdrawInLineImage(img,x-centered, width=new_width, height=new_height)
pdf.showPage()


Enter fullscreen mode Exit fullscreen mode

Step 7

Lastly, we save and run our code

adding images in PDF page

Step 8

Finally, after converting our images we save our newly created PDF file:



pdf.save()


Enter fullscreen mode Exit fullscreen mode

Wrapping it up together:



import tkinter as tk
from tkinter import filedialog
from reportlab.pdfgen import canvas
from PIL import Image
import os

class ImageToPDFConverter:
    def __init__(self, root):
        self.root = root
        self.image_paths = []
        self.output_pdf_name = tk.StringVar()

        self.selected_images_listbox = tk.Listbox(root, selectmode=tk.MULTIPLE)
        self.selected_images_listbox.pack(pady=(0, 10), fill=tk.BOTH, expand=True)

        self.initialize_ui()

    def initialize_ui(self):
        title_label = tk.Label(self.root, text='Image to PDF Converter', font=('Helvetica', 16, 'bold'))
        title_label.pack(pady=10)

        select_image_button = tk.Button(self.root, text='Select Images', command=self.select_images)
        select_image_button.pack(pady=(0, 10))

        label = tk.Label(self.root, text="Enter output PDF name:")
        label.pack()

        pdf_name_entry = tk.Entry(self.root, textvariable=self.output_pdf_name, width=40)
        pdf_name_entry.pack()

        convert_button = tk.Button(self.root, text='Convert to PDF', command=self.convert_images_to_pdf)
        convert_button.pack(pady=(20, 40))

    def select_images(self):
        self.image_paths = filedialog.askopenfilenames(title="Select images", filetypes=[('Image files', '*.png;*.jpg;*.jpeg')])
        self.update_selected_images_listbox()

    def update_selected_images_listbox(self):
        self.selected_images_listbox.delete(0, tk.END)
        for image_path in self.image_paths:
            _, image_name = os.path.split(image_path)
            self.selected_images_listbox.insert(tk.END, image_name)

    def convert_images_to_pdf(self):
        if not self.image_paths:
            return

        output_pdf_path = self.output_pdf_name.get() + ".pdf" if self.output_pdf_name.get() else "output.pdf"

        pdf = canvas.Canvas(output_pdf_path, pagesize=(612, 792))

        for image_path in self.image_paths:
            img = Image.open(image_path)
            available_width = 540
            available_height = 720
            scale_factor = min(available_width / img.width, available_height / img.height)
            new_width = img.width * scale_factor
            new_height = img.height * scale_factor

            x_centered = (612 - new_width) / 2
            y_centered = (792 - new_height) / 2

            pdf.setFillColorRGB(255, 255, 255)
            pdf.rect(0, 0, 612, 792, fill=True)

            pdf.drawImage(img, x_centered, y_centered, width=new_width, height=new_height)
            pdf.showPage()

        pdf.save()

def main():
    root = tk.Tk()
    root.title("Image to PDF")
    converter = ImageToPDFConverter(root)
    root.geometry("400x600")
    root.mainloop()

if __name__ == "__main__":
    main()


Enter fullscreen mode Exit fullscreen mode

Conclusion

The process of developing the image-to-PDF converter app has been an insightful journey from start to finish. We began by identifying the need for such a tool in the market and understanding the requirements of the users. Through careful planning and research, we designed the application's features and functionality to meet these needs effectively. Throughout the development phase, we encountered challenges that we overcame with creativity and problem-solving skills. We implemented key functionalities such as image recognition, file conversion, and user-friendly interface design to ensure a seamless user experience.

The learning outcomes from this project are vast. We gained valuable experience in app development, image processing, file handling, and user interface design. Additionally, we honed our project management and teamwork skills by collaborating effectively to deliver a high-quality product. The practical applications of this image to PDF converter app are significant. Users can now easily convert their images to PDF files with just a few clicks, saving time and effort. This app can be used in various industries such as education, business, and photography, providing a convenient solution for converting and sharing documents.

Overall, developing the image-to-PDF converter app has been a rewarding experience that has equipped us with new skills and knowledge. The app has the potential to make a positive impact on users' productivity and efficiency, demonstrating the power of technology to simplify everyday tasks.

Top comments (0)

Some comments may only be visible to logged-in visitors. Sign in to view all comments.