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
- Imports
- Extract Images from PDF Function
- Browse for PDF Function
- Creating the Main Window
- Creating the Browse PDF Button
- Running the Main Window
- Example
- Full Code
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 frompdf_path
and the directory where they want to save these images after extractionoutput_dir
. It then opens and reads the PDF file usingPdfReader
, 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!