Source code for pdf_manipulation

import os
# import importlib
import shutil
import PyPDF2
import numpy as np
import cv2
from PIL import Image

[docs]def merge_pdfs(input_folder: str, output_folder: str,merged_filename: str) -> None: """ Merge all PDFs in a folder into a single PDF file. Order is determined by the sorting in the OS. Args: input_folder (str): Folder containing PDF files to merge. output_folder (str): Folder to save the merged PDF file. merged_filename (str): Name of the merged PDF file. Returns: None """ pdf_writer = PyPDF2.PdfWriter() for filename in os.listdir(input_folder): if filename.lower().endswith('.pdf'): pdf_file = os.path.join(input_folder, filename) pdf_reader = PyPDF2.PdfReader(pdf_file) for page in range(len(pdf_reader.pages)): pdf_writer.add_page(pdf_reader.pages[page]) output_path = os.path.join(output_folder, merged_filename) with open(output_path, 'wb') as fh: pdf_writer.write(fh)
[docs]def merge_pdfs_in_order(files_list: list,output_folder: str,merged_filename: str) -> None: """ Merge PDFs in a list into a single PDF file. Order is determined by the order of the list. Args: files_list (list): List of PDF filenames to merge. output_folder (str): Folder to save the merged PDF file. merged_filename (str): Name of the merged PDF file. Returns: None """ pdf_writer = PyPDF2.PdfWriter() for pdf_file in files_list: if pdf_file.lower().endswith('.pdf'): pdf_reader = PyPDF2.PdfReader(pdf_file) for page in range(len(pdf_reader.pages)): pdf_writer.add_page(pdf_reader.pages[page]) output_path = os.path.join(output_folder, merged_filename) with open(output_path, 'wb') as fh: pdf_writer.write(fh)
[docs]def convert2pdf_with_order(input_list: list,output_dir: str,merged_filename:str, enhance_img:bool=False): """ Convert a list of images to PDFs and merge them in the order of the list. Optionally enhance the images by converting to greyscale and filtering lower values before conversion. Args: input_list (list): List of image filenames to convert to PDFs. output_dir (str): Folder to save the converted PDFs and the merged PDF file. merged_filename (str): Name of the merged PDF file. enhance_img (bool): Enhance the images before conversion. Default is False. Returns: None """ if enhance_img: processed_image_path = os.path.join(output_dir,"enhanced_images") if os.path.exists(processed_image_path): shutil.rmtree(processed_image_path) os.makedirs(processed_image_path) else: os.makedirs(processed_image_path) converted_pdfs_path = os.path.join(output_dir,"converted_pdfs") if os.path.exists(converted_pdfs_path): shutil.rmtree(converted_pdfs_path) os.makedirs(converted_pdfs_path) else: os.makedirs(converted_pdfs_path) pdf_list = [] for input_image in input_list: if input_image.lower().endswith(('.jpg', '.jpeg', '.png', '.gif')): img_name = os.path.basename(input_image) pdf_list.append(os.path.join(converted_pdfs_path,img_name)+'.pdf') pdf = open(os.path.join(converted_pdfs_path,img_name)+'.pdf', 'wb') if enhance_img: image = enhance_image(input_image,os.path.join(output_dir,"enhanced_images",img_name)) image = Image.fromarray(image) else: image = Image.open(input_image) image = image.convert('RGB') image.save(pdf, 'PDF') pdf.close() merge_pdfs_in_order(pdf_list,output_dir,merged_filename) if enhance_img: shutil.rmtree(processed_image_path) shutil.rmtree(converted_pdfs_path)
[docs]def convert2pdf(input_dir: str,output_dir: str,merged_filename: str,enhance_img: bool=False,delete_processed_images: bool=False,delete_temp_pdfs: bool=False) -> None: """ Convert images in a folder to PDFs and merge them into a single PDF file. Optionally enhance the images by converting to greyscale and filtering lower values before conversion. Args: input_dir (str): Folder containing images to convert to PDFs. output_dir (str): Folder to save the converted PDFs and the merged PDF file. merged_filename (str): Name of the merged PDF file. enhance_img (bool): Enhance the images before conversion. Default is False. delete_processed_images (bool): Delete the processed images after conversion. Default is False. delete_temp_pdfs (bool): Delete the temporary PDF files after merging. Default is False. Returns: None """ image_paths = sorted(os.listdir(input_dir)) if enhance_img: processed_image_path = os.path.join(output_dir,"enhanced_images") if os.path.exists(processed_image_path): shutil.rmtree(processed_image_path) os.makedirs(processed_image_path) else: os.makedirs(processed_image_path) converted_pdfs_path = os.path.join(output_dir,"converted_pdfs") if os.path.exists(converted_pdfs_path): shutil.rmtree(converted_pdfs_path) os.makedirs(converted_pdfs_path) else: os.makedirs(converted_pdfs_path) for input_image in image_paths: if input_image.lower().endswith(('.jpg', '.jpeg', '.png', '.gif')): pdf = open(os.path.join(converted_pdfs_path,input_image)+'.pdf', 'wb') if enhance_img: image = enhance_image(os.path.join(input_dir,input_image),os.path.join(output_dir,"enhanced_images",input_image)) image = Image.fromarray(image) else: image = Image.open(os.path.join(input_dir,input_image)) image = image.convert('RGB') image.save(pdf, 'PDF') pdf.close() merge_pdfs(converted_pdfs_path,output_dir,merged_filename) if delete_processed_images and enhance_img: shutil.rmtree(processed_image_path) if delete_temp_pdfs: shutil.rmtree(converted_pdfs_path)
[docs]def enhance_image(image_path: str,output_path: str) -> np.ndarray: """ Enhance an image by converting to greyscale, denoising, and thresholding. Args: image_path (str): Path to the image file. output_path (str): Path to save the enhanced image. Returns: np.ndarray: Enhanced image as a NumPy array. """ img = cv2.imread(image_path) norm_img = np.zeros((img.shape[0], img.shape[1])) img = cv2.normalize(img, norm_img, 0, 255, cv2.NORM_MINMAX) img = cv2.fastNlMeansDenoisingColored(img, None, 10, 10, 7, 15) img = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) img = cv2.adaptiveThreshold(img,255,cv2.ADAPTIVE_THRESH_GAUSSIAN_C,cv2.THRESH_BINARY,11,2) cv2.imwrite(output_path,img) return img
[docs]def enhance_images(input_dir: str,output_dir: str) -> None: """ Enhance all images in a folder by converting to greyscale, denoising, and thresholding. Args: input_dir (str): Folder containing images to enhance. output_dir (str): Folder to save the enhanced images. Returns: None """ image_paths = sorted(os.listdir(input_dir)) for image in image_paths: enhance_image(os.path.join(input_dir,image),os.path.join(output_dir,image))
[docs]def pdf_splitter(path:str,out_dir:str,start_page:int,end_page:int) -> None: """ Split a PDF file into multiple PDF files based on the start and end page numbers. Args: path (str): Path to the PDF file. out_dir (str): Folder to save the split PDF files. start_page (int): Start page number. end_page (int): End page number. Returns: None """ fname = os.path.splitext(os.path.basename(path))[0] pdf = PyPDF2.PdfReader(path) if pdf.isEncrypted: if not pdf.decrypt(''): password = input("Document is encrypted. Enter password: ") # simpledialog = importlib.import_module('tkinter.simpledialog') # password = simpledialog.askstring("Document is encrypted.", "Enter password:",show='*') if not pdf.decrypt(password): raise Exception("Decryption failed.") pdf_writer = PyPDF2.PdfWriter() for page in range(start_page-1,end_page): pdf_writer.add_page(pdf.pages[page]) output_filename =os.path.join( out_dir,'{}_pages_{}-{}.pdf'.format(fname, start_page,end_page)) with open(output_filename, 'wb') as out: pdf_writer.write(out)