Home » Tutorials » How to Extract Images from PDF in Python

How to Extract Images from PDF in Python

In today’s world, pulling images out of PDFs can come in handy, whether you’re making something new, digging into data, or just organizing stuff. That’s why we’re here to walk you through building your very own image extractor using Python.

In this tutorial, you’ll learn how to extract images from PDF in Python. This guide is all about keeping things simple and letting you add your own twist. So, grab your favorite IDE, and let’s start this coding adventure together!

Table of Contents

Necessary Libraries

Make sure to install the tkinter, PyPDF2, and Pillow libraries via the terminal or your command prompt for the code to function properly:

$ pip install tk
$ pip install PyPDF2 
$ pip install Pillow

Imports

import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from PyPDF2 import PdfReader
import os
import io
from PIL import Image
import re

First, we import the tkinter library to enable the creation of graphical user interfaces. We also import filedialog and messagebox modules from tkinter for opening files, saving images, and using message boxes, respectively. For PDF file reading, we import PdfReader.

In the next step, the os module comes into play for interacting with the operating system, followed by the io module, which supports working with streams of data. For image processing, we use Image from the Python Imaging Library (PIL).

Finally, we import re to work with regular expressions for string manipulation, rounding off our set of tools for this project.

Extract Images from PDF Function

After importing the necessary libraries and modules, it’s time to define the heartbeat of our code. So, we start by defining this function:

  • The extract_images_from_pdf() function begins by collecting the user’s inputs, specifically the PDF file they wish to extract images from pdf_path and the directory where they want to save these images after extraction output_dir. It then opens and reads the PDF file using PdfReader, setting the stage for image extraction.
  • Next, the function iterates through each page of the PDF, employing enumerate to diligently search for images. Upon discovering any images, it extracts them and appends them to a previously initialized list, images = [].
  • The process concludes with the function saving these extracted images in the specified output_dir, each under a unique filename, ensuring easy retrieval and organization.
def extract_images_from_pdf(pdf_path, output_dir):
   images = []
   with open(pdf_path, 'rb') as f:
       reader = PdfReader(f)
       for page_num, page in enumerate(reader.pages):
           if '/XObject' in page['/Resources']:
               xObject = page['/Resources'].get('/XObject')
               for obj in xObject:
                   obj_ref = xObject[obj]
                   if obj_ref.get('/Subtype') == '/Image':
                       size = (obj_ref['/Width'], obj_ref['/Height'])
                       data = obj_ref.get_data()
                       mode = ''
                       if obj_ref.get('/ColorSpace') == '/DeviceRGB':
                           mode = 'RGB'
                       else:
                           mode = 'P'


                       if obj_ref.get('/Filter'):
                           if obj_ref['/Filter'] == '/FlateDecode':
                               img = Image.frombytes(mode, size, data)
                               images.append(img)
                           elif obj_ref['/Filter'] == '/DCTDecode':
                               img = io.BytesIO(data)
                               img = Image.open(img)
                               images.append(img)
                               obj_name = re.sub(r'[^a-zA-Z0-9]', '_', obj)  # Replace invalid characters
                               file_path = os.path.join(output_dir, f"extracted_image_{page_num}_{obj_name}.jpg")
                               img.save(file_path)  # Save the image to the chosen directory
   return images

Browse for PDF Function

def browse_pdf():
   filename = filedialog.askopenfilename(filetypes=[("PDF files", "*.pdf")])
   if filename:
       output_dir = filedialog.askdirectory(title="Select Directory to Save Images")
       if output_dir:
           extracted_images = extract_images_from_pdf(filename, output_dir)
           messagebox.showinfo("Extraction Complete", f"{len(extracted_images)} images extracted successfully.")

This one operates simply: upon activation, it first opens a dialog allowing the user to select the PDF file from which they want to extract images. Subsequently, another dialog appears for the user to choose the destination for the extracted images.

After these selections are made, it calls the extract_images_from_pdf() function to perform the extraction. Upon successful extraction, a message is displayed indicating the number of images extracted.

Creating the Main Window

For this step, we created the main window and set its title and geometry.

# Tkinter GUI
root = tk.Tk()
root.title("PDF Image Extractor - The Pycodes")
root.geometry("400x100")

Creating the Browse PDF Button

Following that, we created a button that, when clicked, triggers the browse_pdf() function. It is called the “Browse PDF” button.

browse_button = tk.Button(root, text="Browse PDF", command=browse_pdf,width=20)
browse_button.pack(pady=20)

Running the Main Window

Lastly, this part ensures that the main window remains operational and responsive to user interactions until it is closed intentionally.

root.mainloop()

Example

Full Code

import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from PyPDF2 import PdfReader
import os
import io
from PIL import Image
import re


def extract_images_from_pdf(pdf_path, output_dir):
   images = []
   with open(pdf_path, 'rb') as f:
       reader = PdfReader(f)
       for page_num, page in enumerate(reader.pages):
           if '/XObject' in page['/Resources']:
               xObject = page['/Resources'].get('/XObject')
               for obj in xObject:
                   obj_ref = xObject[obj]
                   if obj_ref.get('/Subtype') == '/Image':
                       size = (obj_ref['/Width'], obj_ref['/Height'])
                       data = obj_ref.get_data()
                       mode = ''
                       if obj_ref.get('/ColorSpace') == '/DeviceRGB':
                           mode = 'RGB'
                       else:
                           mode = 'P'


                       if obj_ref.get('/Filter'):
                           if obj_ref['/Filter'] == '/FlateDecode':
                               img = Image.frombytes(mode, size, data)
                               images.append(img)
                           elif obj_ref['/Filter'] == '/DCTDecode':
                               img = io.BytesIO(data)
                               img = Image.open(img)
                               images.append(img)
                               obj_name = re.sub(r'[^a-zA-Z0-9]', '_', obj)  # Replace invalid characters
                               file_path = os.path.join(output_dir, f"extracted_image_{page_num}_{obj_name}.jpg")
                               img.save(file_path)  # Save the image to the chosen directory
   return images


def browse_pdf():
   filename = filedialog.askopenfilename(filetypes=[("PDF files", "*.pdf")])
   if filename:
       output_dir = filedialog.askdirectory(title="Select Directory to Save Images")
       if output_dir:
           extracted_images = extract_images_from_pdf(filename, output_dir)
           messagebox.showinfo("Extraction Complete", f"{len(extracted_images)} images extracted successfully.")


# Tkinter GUI
root = tk.Tk()
root.title("PDF Image Extractor - The Pycodes")
root.geometry("400x100")


browse_button = tk.Button(root, text="Browse PDF", command=browse_pdf,width=20)
browse_button.pack(pady=20)


root.mainloop()

Happy Coding!

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top