{ "cells": [ { "cell_type": "code", "execution_count": 25, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Front pages PDF saved as: booklet_front.pdf\n", "Back pages PDF saved as: booklet_back.pdf\n" ] } ], "source": [ "import math\n", "import io\n", "from PyPDF2 import PdfReader, PdfWriter\n", "\n", "def create_booklet_with_blank_pages(pdf_path, output_front_path, output_back_path):\n", " try:\n", " # Step 1: Read the PDF using the file path\n", " reader = PdfReader(pdf_path)\n", " total_pages = len(reader.pages)\n", "\n", " # Step 2: Ensure the number of pages is divisible by 4 by adding blank pages if needed\n", " writer = PdfWriter()\n", " for page in reader.pages:\n", " writer.add_page(page)\n", "\n", " # Calculate how many blank pages are needed\n", " remainder = total_pages % 4\n", " blank_pages_needed = (4 - remainder) if remainder > 0 else 0\n", "\n", " # Step 3: Add the necessary number of blank pages\n", " for _ in range(blank_pages_needed):\n", " writer.add_blank_page() # Add a blank page directly\n", "\n", " # Step 4: Write the new PDF with added blank pages to a BytesIO stream\n", " modified_pdf = io.BytesIO()\n", " writer.write(modified_pdf)\n", " modified_pdf.seek(0)\n", "\n", " # Step 5: Create the front and back arrangement for booklet-style printing\n", " modified_reader = PdfReader(modified_pdf)\n", " total_pages = len(modified_reader.pages)\n", "\n", " # Create writers for the front and back pages\n", " front_writer = PdfWriter()\n", " back_writer = PdfWriter()\n", "\n", " # Arrange pages for the front: (e.g., 8 & 1, 6 & 3)\n", " for i in range(total_pages // 4):\n", " front_writer.add_page(modified_reader.pages[total_pages - 1 - (2 * i)])\n", " front_writer.add_page(modified_reader.pages[2 * i])\n", "\n", " # Arrange pages for the back: (e.g., 2 & 7, 4 & 5)\n", " for i in range(total_pages // 4):\n", " back_writer.add_page(modified_reader.pages[2 * i + 1])\n", " back_writer.add_page(modified_reader.pages[total_pages - 2 - (2 * i)])\n", "\n", " # Step 6: Write the front and back PDFs to the specified output paths\n", " with open(output_front_path, \"wb\") as front_file:\n", " front_writer.write(front_file)\n", "\n", " with open(output_back_path, \"wb\") as back_file:\n", " back_writer.write(back_file)\n", "\n", " print(f\"Front pages PDF saved as: {output_front_path}\")\n", " print(f\"Back pages PDF saved as: {output_back_path}\")\n", "\n", " except Exception as e:\n", " print(f\"Error during PDF processing: {str(e)}\")\n", "\n", "# Example usage\n", "pdf_path = \"input.pdf\" # Replace with your input PDF path\n", "output_front_path = \"booklet_front.pdf\"\n", "output_back_path = \"booklet_back.pdf\"\n", "create_booklet_with_blank_pages(pdf_path, output_front_path, output_back_path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## attempt to directly merge the 2 pages together" ] }, { "cell_type": "code", "execution_count": 48, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Front pages PDF saved as: booklet_front.pdf\n", "Back pages PDF saved as: booklet_back.pdf\n" ] } ], "source": [ "import tempfile\n", "from PyPDF2 import PdfReader, PdfWriter, PageObject\n", "\n", "def merge_two_pages_on_one(page1, page2):\n", " \"\"\"\n", " Merges two PDF pages into a single PDF page (side by side).\n", " \"\"\"\n", " # Create a new blank page with double width to place the two pages side by side\n", " width = page1.mediabox.width + page2.mediabox.width\n", " height = max(page1.mediabox.height, page2.mediabox.height)\n", " \n", " new_page = PageObject.create_blank_page(width=width, height=height)\n", "\n", " # Merge page1 on the left side\n", " new_page.merge_page(page1)\n", "\n", " # Translate page2 to the right by the width of page1\n", " page2_content = PageObject.create_blank_page(width=width, height=height)\n", " page2_content.merge_page(page2)\n", " page2_content.add_transformation([1, 0, 0, 1, page1.mediabox.width, 0]) # x translation by page1 width\n", "\n", " # Merge the translated page2 onto the new page\n", " new_page.merge_page(page2_content)\n", "\n", " return new_page\n", "\n", "def create_booklet_with_two_pages_per_sheet(pdf_path, output_front_path, output_back_path):\n", " try:\n", " # Step 1: Read the PDF using the file path\n", " reader = PdfReader(pdf_path)\n", " total_pages = len(reader.pages)\n", "\n", " # Step 2: Ensure the number of pages is divisible by 4 by adding blank pages if needed\n", " writer = PdfWriter()\n", " for page in reader.pages:\n", " writer.add_page(page)\n", "\n", " # Calculate how many blank pages are needed\n", " remainder = total_pages % 4\n", " blank_pages_needed = (4 - remainder) if remainder > 0 else 0\n", "\n", " # Step 3: Add the necessary number of blank pages\n", " for _ in range(blank_pages_needed):\n", " writer.add_blank_page() # Add a blank page directly\n", "\n", " # Step 4: Write the new PDF with added blank pages to a temporary file\n", " with tempfile.NamedTemporaryFile(delete=False, suffix=\".pdf\") as temp_pdf_file:\n", " writer.write(temp_pdf_file)\n", " temp_pdf_path = temp_pdf_file.name\n", "\n", " # Read the modified PDF back\n", " modified_reader = PdfReader(temp_pdf_path)\n", " total_pages = len(modified_reader.pages)\n", "\n", " # Create writers for the front and back pages\n", " front_writer = PdfWriter()\n", " back_writer = PdfWriter()\n", "\n", " # Arrange pages for the front: (e.g., 8 & 1, 6 & 3)\n", " for i in range(total_pages // 4):\n", " page1 = modified_reader.pages[total_pages - 1 - (2 * i)]\n", " page2 = modified_reader.pages[2 * i]\n", "\n", " # Merge the two pages onto one sheet\n", " merged_page = merge_two_pages_on_one(page1, page2)\n", " front_writer.add_page(merged_page)\n", "\n", " # Arrange pages for the back: (e.g., 2 & 7, 4 & 5)\n", " for i in range(total_pages // 4):\n", " page1 = modified_reader.pages[2 * i + 1]\n", " page2 = modified_reader.pages[total_pages - 2 - (2 * i)]\n", "\n", " # Merge the two pages onto one sheet\n", " merged_page = merge_two_pages_on_one(page1, page2)\n", " back_writer.add_page(merged_page)\n", "\n", " # Step 5: Write the front and back PDFs to the specified output paths\n", " with open(output_front_path, \"wb\") as front_file:\n", " front_writer.write(front_file)\n", "\n", " with open(output_back_path, \"wb\") as back_file:\n", " back_writer.write(back_file)\n", "\n", " print(f\"Front pages PDF saved as: {output_front_path}\")\n", " print(f\"Back pages PDF saved as: {output_back_path}\")\n", "\n", " except Exception as e:\n", " print(f\"Error during PDF processing: {str(e)}\")\n", "\n", "# Example usage\n", "pdf_path = \"input.pdf\" # Replace with your input PDF path\n", "output_front_path = \"booklet_front.pdf\"\n", "output_back_path = \"booklet_back.pdf\"\n", "create_booklet_with_two_pages_per_sheet(pdf_path, output_front_path, output_back_path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Booklet with reverse and normal back" ] }, { "cell_type": "code", "execution_count": 3, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Front pages PDF saved as: booklet_front.pdf\n", "Back pages PDF saved as: booklet_back.pdf\n", "Reversed PDF saved as: reversed_booklet_back.pdf\n" ] } ], "source": [ "import tempfile\n", "from PyPDF2 import PdfReader, PdfWriter, PageObject\n", "\n", "def merge_two_pages_on_one(page1, page2):\n", " \"\"\"\n", " Merges two PDF pages into a single PDF page (side by side).\n", " \"\"\"\n", " # Create a new blank page with double width to place the two pages side by side\n", " width = page1.mediabox.width + page2.mediabox.width\n", " height = max(page1.mediabox.height, page2.mediabox.height)\n", " \n", " new_page = PageObject.create_blank_page(width=width, height=height)\n", "\n", " # Merge page1 on the left side\n", " new_page.merge_page(page1)\n", "\n", " # Translate page2 to the right by the width of page1\n", " page2_content = PageObject.create_blank_page(width=width, height=height)\n", " page2_content.merge_page(page2)\n", " page2_content.add_transformation([1, 0, 0, 1, page1.mediabox.width, 0]) # x translation by page1 width\n", "\n", " # Merge the translated page2 onto the new page\n", " new_page.merge_page(page2_content)\n", "\n", " return new_page\n", "\n", "def reverse_pdf(input_pdf_path, output_pdf_path):\n", " \"\"\"\n", " Reverses the order of pages in a PDF.\n", " \"\"\"\n", " try:\n", " # Step 1: Read the PDF using the file path\n", " reader = PdfReader(input_pdf_path)\n", " total_pages = len(reader.pages)\n", "\n", " # Step 2: Create a writer and add pages in reverse order\n", " writer = PdfWriter()\n", " for page_num in reversed(range(total_pages)):\n", " writer.add_page(reader.pages[page_num])\n", "\n", " # Step 3: Write the reversed pages to the new PDF\n", " with open(output_pdf_path, \"wb\") as output_file:\n", " writer.write(output_file)\n", "\n", " print(f\"Reversed PDF saved as: {output_pdf_path}\")\n", "\n", " except Exception as e:\n", " print(f\"Error during PDF reversing: {str(e)}\")\n", "\n", "def create_booklet_with_two_pages_per_sheet(pdf_path, output_front_path, output_back_path, output_reversed_back_path):\n", " try:\n", " # Step 1: Read the PDF using the file path\n", " reader = PdfReader(pdf_path)\n", " total_pages = len(reader.pages)\n", "\n", " # Step 2: Ensure the number of pages is divisible by 4 by adding blank pages if needed\n", " writer = PdfWriter()\n", " for page in reader.pages:\n", " writer.add_page(page)\n", "\n", " # Calculate how many blank pages are needed\n", " remainder = total_pages % 4\n", " blank_pages_needed = (4 - remainder) if remainder > 0 else 0\n", "\n", " # Step 3: Add the necessary number of blank pages\n", " for _ in range(blank_pages_needed):\n", " writer.add_blank_page() # Add a blank page directly\n", "\n", " # Step 4: Write the new PDF with added blank pages to a temporary file\n", " with tempfile.NamedTemporaryFile(delete=False, suffix=\".pdf\") as temp_pdf_file:\n", " writer.write(temp_pdf_file)\n", " temp_pdf_path = temp_pdf_file.name\n", "\n", " # Read the modified PDF back\n", " modified_reader = PdfReader(temp_pdf_path)\n", " total_pages = len(modified_reader.pages)\n", "\n", " # Create writers for the front and back pages\n", " front_writer = PdfWriter()\n", " back_writer = PdfWriter()\n", "\n", " # Arrange pages for the front: (e.g., 8 & 1, 6 & 3)\n", " for i in range(total_pages // 4):\n", " page1 = modified_reader.pages[total_pages - 1 - (2 * i)]\n", " page2 = modified_reader.pages[2 * i]\n", "\n", " # Merge the two pages onto one sheet\n", " merged_page = merge_two_pages_on_one(page1, page2)\n", " front_writer.add_page(merged_page)\n", "\n", " # Arrange pages for the back: (e.g., 2 & 7, 4 & 5)\n", " for i in range(total_pages // 4):\n", " page1 = modified_reader.pages[2 * i + 1]\n", " page2 = modified_reader.pages[total_pages - 2 - (2 * i)]\n", "\n", " # Merge the two pages onto one sheet\n", " merged_page = merge_two_pages_on_one(page1, page2)\n", " back_writer.add_page(merged_page)\n", "\n", " # Step 5: Write the front and back PDFs to the specified output paths\n", " with open(output_front_path, \"wb\") as front_file:\n", " front_writer.write(front_file)\n", "\n", " with open(output_back_path, \"wb\") as back_file:\n", " back_writer.write(back_file)\n", "\n", " print(f\"Front pages PDF saved as: {output_front_path}\")\n", " print(f\"Back pages PDF saved as: {output_back_path}\")\n", "\n", " # Step 6: Reverse the back PDF pages\n", " reverse_pdf(output_back_path, output_reversed_back_path)\n", "\n", " except Exception as e:\n", " print(f\"Error during PDF processing: {str(e)}\")\n", "\n", "# Example usage\n", "pdf_path = \"Calculus_Module.pdf\" # Replace with your input PDF path\n", "output_front_path = \"booklet_front.pdf\"\n", "output_back_path = \"booklet_back.pdf\"\n", "output_reversed_back_path = \"reversed_booklet_back.pdf\"\n", "create_booklet_with_two_pages_per_sheet(pdf_path, output_front_path, output_back_path, output_reversed_back_path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# Booklet Reversed Back" ] }, { "cell_type": "code", "execution_count": 50, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Front pages PDF saved as: booklet_front.pdf\n", "Back pages PDF (already reversed) saved as: booklet_back.pdf\n" ] } ], "source": [ "import tempfile\n", "from PyPDF2 import PdfReader, PdfWriter, PageObject\n", "\n", "def merge_two_pages_on_one(page1, page2):\n", " \"\"\"\n", " Merges two PDF pages into a single PDF page (side by side).\n", " \"\"\"\n", " # Create a new blank page with double width to place the two pages side by side\n", " width = page1.mediabox.width + page2.mediabox.width\n", " height = max(page1.mediabox.height, page2.mediabox.height)\n", " \n", " new_page = PageObject.create_blank_page(width=width, height=height)\n", "\n", " # Merge page1 on the left side\n", " new_page.merge_page(page1)\n", "\n", " # Translate page2 to the right by the width of page1\n", " page2_content = PageObject.create_blank_page(width=width, height=height)\n", " page2_content.merge_page(page2)\n", " page2_content.add_transformation([1, 0, 0, 1, page1.mediabox.width, 0]) # x translation by page1 width\n", "\n", " # Merge the translated page2 onto the new page\n", " new_page.merge_page(page2_content)\n", "\n", " return new_page\n", "\n", "def create_booklet_with_two_pages_per_sheet(pdf_path, output_front_path, output_back_path):\n", " try:\n", " # Step 1: Read the PDF using the file path\n", " reader = PdfReader(pdf_path)\n", " total_pages = len(reader.pages)\n", "\n", " # Step 2: Ensure the number of pages is divisible by 4 by adding blank pages if needed\n", " writer = PdfWriter()\n", " for page in reader.pages:\n", " writer.add_page(page)\n", "\n", " # Calculate how many blank pages are needed\n", " remainder = total_pages % 4\n", " blank_pages_needed = (4 - remainder) if remainder > 0 else 0\n", "\n", " # Step 3: Add the necessary number of blank pages\n", " for _ in range(blank_pages_needed):\n", " writer.add_blank_page() # Add a blank page directly\n", "\n", " # Step 4: Write the new PDF with added blank pages to a temporary file\n", " with tempfile.NamedTemporaryFile(delete=False, suffix=\".pdf\") as temp_pdf_file:\n", " writer.write(temp_pdf_file)\n", " temp_pdf_path = temp_pdf_file.name\n", "\n", " # Read the modified PDF back\n", " modified_reader = PdfReader(temp_pdf_path)\n", " total_pages = len(modified_reader.pages)\n", "\n", " # Create writers for the front and back pages\n", " front_writer = PdfWriter()\n", " back_writer = PdfWriter()\n", "\n", " # Arrange pages for the front: (e.g., 8 & 1, 6 & 3)\n", " for i in range(total_pages // 4):\n", " page1 = modified_reader.pages[total_pages - 1 - (2 * i)]\n", " page2 = modified_reader.pages[2 * i]\n", "\n", " # Merge the two pages onto one sheet\n", " merged_page = merge_two_pages_on_one(page1, page2)\n", " front_writer.add_page(merged_page)\n", "\n", " # Arrange pages for the back, but in reverse order directly: (e.g., 2 & 7, 4 & 5)\n", " for i in reversed(range(total_pages // 4)):\n", " page1 = modified_reader.pages[2 * i + 1]\n", " page2 = modified_reader.pages[total_pages - 2 - (2 * i)]\n", "\n", " # Merge the two pages onto one sheet\n", " merged_page = merge_two_pages_on_one(page1, page2)\n", " back_writer.add_page(merged_page)\n", "\n", " # Step 5: Write the front and reversed back PDFs to the specified output paths\n", " with open(output_front_path, \"wb\") as front_file:\n", " front_writer.write(front_file)\n", "\n", " with open(output_back_path, \"wb\") as back_file:\n", " back_writer.write(back_file)\n", "\n", " print(f\"Front pages PDF saved as: {output_front_path}\")\n", " print(f\"Back pages PDF (already reversed) saved as: {output_back_path}\")\n", "\n", " except Exception as e:\n", " print(f\"Error during PDF processing: {str(e)}\")\n", "\n", "# Example usage\n", "pdf_path = \"input.pdf\" # Replace with your input PDF path\n", "output_front_path = \"booklet_front.pdf\"\n", "output_back_path = \"booklet_back.pdf\"\n", "create_booklet_with_two_pages_per_sheet(pdf_path, output_front_path, output_back_path)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# With UI" ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [ { "name": "stderr", "output_type": "stream", "text": [ "/Users/nicoaspra/Documents/Professor/Jupyter Notebook/venv/lib/python3.12/site-packages/tqdm/auto.py:21: TqdmWarning: IProgress not found. Please update jupyter and ipywidgets. See https://ipywidgets.readthedocs.io/en/stable/user_install.html\n", " from .autonotebook import tqdm as notebook_tqdm\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "Running on local URL: http://127.0.0.1:7860\n", "\n", "To create a public link, set `share=True` in `launch()`.\n" ] }, { "data": { "text/html": [ "
" ], "text/plain": [ "