### Install poppler on Ubuntu Source: https://github.com/belval/pdf2image/blob/master/docs/installation.md Install the poppler-utils package using apt. ```bash sudo apt-get install poppler-utils ``` -------------------------------- ### Install pdf2image from source Source: https://github.com/belval/pdf2image/blob/master/docs/installation.md Execute this command after cloning the repository to install the package. ```bash python3 setup.py install ``` -------------------------------- ### Install poppler on Archlinux Source: https://github.com/belval/pdf2image/blob/master/docs/installation.md Install the poppler package using pacman. ```bash sudo pacman -S poppler ``` -------------------------------- ### Install pdf2image via pip Source: https://github.com/belval/pdf2image/blob/master/docs/installation.md Standard installation method using the Python package manager. ```bash pip install pdf2image ``` -------------------------------- ### Install poppler on MacOS Source: https://github.com/belval/pdf2image/blob/master/docs/installation.md Install poppler using the Homebrew package manager. ```bash brew install poppler ``` -------------------------------- ### Install dependencies via Conda Source: https://github.com/belval/pdf2image/blob/master/README.md Platform-independent installation steps using the conda package manager. ```bash conda install -c conda-forge poppler pip install pdf2image ``` -------------------------------- ### Install Poppler system dependency Source: https://github.com/belval/pdf2image/blob/master/_autodocs/00-START-HERE.md System-level installation commands for Poppler on macOS and Linux. ```bash brew install poppler ``` ```bash apt-get install poppler-utils ``` -------------------------------- ### Configuring JPEG Conversion Source: https://github.com/belval/pdf2image/blob/master/_autodocs/types.md Example of passing a JPEG options dictionary to the convert_from_path function. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", fmt="jpeg", jpegopt={ "quality": 85, "progressive": True, "optimize": True } ) ``` -------------------------------- ### Verify pdf2image Installation Source: https://github.com/belval/pdf2image/blob/master/_autodocs/00-START-HERE.md Use this snippet to confirm that the library is correctly installed and the poppler dependency is accessible. ```python from pdf2image import convert_from_path # If this doesn't error, you're installed correctly images = convert_from_path('/path/to/sample.pdf') ``` -------------------------------- ### Verify poppler installation Source: https://github.com/belval/pdf2image/blob/master/docs/installation.md Check if the poppler utility is correctly installed and accessible in your system path. ```bash pdftoppm -h ``` -------------------------------- ### Custom prefix, suffix, and padding usage Source: https://github.com/belval/pdf2image/blob/master/_autodocs/generators.md Example of configuring the generator with custom prefix, suffix, and padding width. ```python from pdf2image import convert_from_path from pdf2image.generators import counter_generator gen = counter_generator(prefix="doc_", suffix="_page", padding_goal=3) images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file=gen ) # Creates files: # /tmp/output/doc_001_page.ppm # /tmp/output/doc_002_page.ppm # /tmp/output/doc_003_page.ppm ``` -------------------------------- ### No padding usage Source: https://github.com/belval/pdf2image/blob/master/_autodocs/generators.md Example of using the generator with minimal padding. ```python from pdf2image import convert_from_path from pdf2image.generators import counter_generator gen = counter_generator(prefix="page_", padding_goal=1) images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file=gen ) # Creates files: # /tmp/output/page_1.ppm # /tmp/output/page_2.ppm # /tmp/output/page_3.ppm ``` -------------------------------- ### Handle PDFInfoNotInstalledError Source: https://github.com/belval/pdf2image/blob/master/_autodocs/exceptions.md Example of catching the PDFInfoNotInstalledError when calling pdfinfo_from_path. ```python from pdf2image import pdfinfo_from_path from pdf2image.exceptions import PDFInfoNotInstalledError try: info = pdfinfo_from_path("/path/to/document.pdf") page_count = info["Pages"] except PDFInfoNotInstalledError: print("pdfinfo utility not found. Install poppler-utils.") ``` -------------------------------- ### Convert PDF to images using PPM format Source: https://github.com/belval/pdf2image/blob/master/_autodocs/parsers.md Example of using convert_from_path with the default PPM format, which triggers the internal use of parse_buffer_to_ppm. ```python from pdf2image import convert_from_path # PPM is the default format images = convert_from_path("/path/to/document.pdf", fmt="ppm") # Uses parse_buffer_to_ppm internally ``` -------------------------------- ### Basic numbered output usage Source: https://github.com/belval/pdf2image/blob/master/_autodocs/generators.md Example of using counter_generator with a simple prefix to name output files. ```python from pdf2image import convert_from_path from pdf2image.generators import counter_generator gen = counter_generator(prefix="page_") images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file=gen ) # Creates files: # /tmp/output/page_0001.ppm # /tmp/output/page_0002.ppm # /tmp/output/page_0003.ppm ``` -------------------------------- ### Use ThreadSafeGenerator with convert_from_path Source: https://github.com/belval/pdf2image/blob/master/_autodocs/generators.md Example of wrapping a generator to safely handle output filenames across multiple threads. ```python from pdf2image import convert_from_path from pdf2image.generators import ThreadSafeGenerator, counter_generator # Wrap a generator for thread-safe access gen = ThreadSafeGenerator(counter_generator(prefix="page_")) # Safe to use with multiple threads images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file=gen, thread_count=4 ) ``` -------------------------------- ### Define function signature with type hints Source: https://github.com/belval/pdf2image/blob/master/_autodocs/module-structure.md Example of a public function signature utilizing PEP 484 type hints for parameters and return values. ```python def convert_from_path( pdf_path: Union[str, PurePath], dpi: int = 200, ... ) -> List[Image.Image]: ``` -------------------------------- ### Get metadata from bytes in memory Source: https://github.com/belval/pdf2image/blob/master/_autodocs/api-reference-main-functions.md Shows how to read a local file into memory as bytes and extract its metadata. ```python from pdf2image import pdfinfo_from_bytes with open("/path/to/document.pdf", "rb") as f: pdf_bytes = f.read() info = pdfinfo_from_bytes(pdf_bytes) title = info.get("Title", "Unknown") ``` -------------------------------- ### Convert PDF to PNG images Source: https://github.com/belval/pdf2image/blob/master/_autodocs/parsers.md Usage examples for converting PDF files to PNG format using convert_from_path, which utilizes the parser internally. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", fmt="png", dpi=150 ) # Uses parse_buffer_to_png internally # With transparency images = convert_from_path( "/path/to/document.pdf", fmt="png", transparent=True, # Requires pdftocairo dpi=150 ) ``` -------------------------------- ### Get all metadata from a PDF Source: https://github.com/belval/pdf2image/blob/master/_autodocs/api-reference-main-functions.md Iterates through and prints all available metadata fields returned by the function. ```python from pdf2image import pdfinfo_from_path info = pdfinfo_from_path("/path/to/document.pdf") for key, value in info.items(): print(f"{key}: {value}") ``` -------------------------------- ### High padding usage Source: https://github.com/belval/pdf2image/blob/master/_autodocs/generators.md Example of using the generator with high padding for large document sets. ```python from pdf2image import convert_from_path from pdf2image.generators import counter_generator gen = counter_generator(prefix="p", padding_goal=6) images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file=gen ) # Creates files with 6-digit padding: # /tmp/output/p000001.ppm # /tmp/output/p000002.ppm ``` -------------------------------- ### Run performance benchmarks Source: https://github.com/belval/pdf2image/blob/master/README.md Execute the project's test suite to determine optimal settings for your specific environment. ```bash python tests.py ``` -------------------------------- ### Apply size parameter in convert_from_path Source: https://github.com/belval/pdf2image/blob/master/_autodocs/types.md Demonstrates various size configurations when converting PDF files. ```python from pdf2image import convert_from_path # Square aspect-preserving images1 = convert_from_path("doc.pdf", size=400) # Width specified, height proportional images2 = convert_from_path("doc.pdf", size=(400, None)) # Both specified, no aspect ratio preservation images3 = convert_from_path("doc.pdf", size=(500, 500)) # No resizing images4 = convert_from_path("doc.pdf", size=None) ``` -------------------------------- ### Apply format parameter in convert_from_path Source: https://github.com/belval/pdf2image/blob/master/_autodocs/types.md Shows equivalent ways to specify image formats. ```python from pdf2image import convert_from_path # All of these work identically images1 = convert_from_path("doc.pdf", fmt="jpeg") images2 = convert_from_path("doc.pdf", fmt="jpg") images3 = convert_from_path("doc.pdf", fmt="JPEG") images4 = convert_from_path("doc.pdf", fmt=".jpg") ``` -------------------------------- ### Define format constants Source: https://github.com/belval/pdf2image/blob/master/_autodocs/module-structure.md List of file formats that support transparency. ```python TRANSPARENT_FILE_TYPES = ["png", "tiff"] ``` -------------------------------- ### Display project file structure Source: https://github.com/belval/pdf2image/blob/master/_autodocs/00-START-HERE.md Visual representation of the documentation directory layout. ```text output/ ├── 00-START-HERE.md ← You are here ├── README.md ← Master index ├── api-reference-main-functions.md ← All functions ├── configuration.md ← All parameters ├── exceptions.md ← Error handling ├── types.md ← Type system ├── generators.md ← Filename generation ├── parsers.md ← Image format parsing ├── module-structure.md ← Architecture ├── advanced-usage-patterns.md ← Real-world examples └── MANIFEST.md ← Coverage summary ``` -------------------------------- ### Handle PDFPageCountError Source: https://github.com/belval/pdf2image/blob/master/_autodocs/exceptions.md Example of catching a PDFPageCountError when retrieving PDF information. ```python from pdf2image import pdfinfo_from_path from pdf2image.exceptions import PDFPageCountError try: info = pdfinfo_from_path("/path/to/document.pdf") except PDFPageCountError as e: print(f"Cannot read PDF: {e}") # The PDF file may be corrupted or not a valid PDF ``` -------------------------------- ### Handle PopplerNotInstalledError Source: https://github.com/belval/pdf2image/blob/master/_autodocs/exceptions.md Example of catching the PopplerNotInstalledError when attempting to convert a PDF. ```python from pdf2image import convert_from_path from pdf2image.exceptions import PopplerNotInstalledError try: images = convert_from_path("/path/to/document.pdf") except PopplerNotInstalledError: print("Error: Poppler is not installed. Please install it first.") # Install instructions: # macOS: brew install poppler # Linux: apt-get install poppler-utils (or equivalent for your distro) # Windows: Download from https://github.com/oschwartz10612/poppler-windows ``` -------------------------------- ### Define PopplerNotInstalledError class Source: https://github.com/belval/pdf2image/blob/master/_autodocs/exceptions.md The base exception class for poppler installation errors. ```python class PopplerNotInstalledError(Exception): """Raised when poppler is not installed""" ``` -------------------------------- ### Usage of PGM conversion Source: https://github.com/belval/pdf2image/blob/master/_autodocs/parsers.md Demonstrates how to trigger the internal PGM parser by setting the format to ppm and enabling grayscale. ```python from pdf2image import convert_from_path # Used internally when fmt="ppm" and grayscale=True images = convert_from_path( "/path/to/document.pdf", fmt="ppm", grayscale=True ) # Uses parse_buffer_to_pgm internally ``` -------------------------------- ### Apply threadsafe decorator Source: https://github.com/belval/pdf2image/blob/master/_autodocs/generators.md Example usage of the threadsafe decorator on a custom generator function. ```python from pdf2image.generators import threadsafe @threadsafe def my_generator(): i = 0 while True: yield f"file_{i}" i += 1 # my_generator() returns ThreadSafeGenerator automatically gen = my_generator() # Safe to call from multiple threads for _ in range(4): name = next(gen) # Thread-safe access ``` -------------------------------- ### Convert PDF using an output folder Source: https://github.com/belval/pdf2image/blob/master/docs/overview.md Use a temporary directory to store images on disk instead of keeping them entirely in memory. ```python import tempfile from pdf2image import convert_from_path with tempfile.TemporaryDirectory() as path: images_from_path = convert_from_path("/home/user/example.pdf", output_folder=path) ``` -------------------------------- ### Get page count from PDF Source: https://github.com/belval/pdf2image/blob/master/_autodocs/api-reference-main-functions.md Extracts the total page count from a PDF file. ```python from pdf2image import pdfinfo_from_path info = pdfinfo_from_path("/path/to/document.pdf") print(f"PDF has {info['Pages']} pages") ``` -------------------------------- ### Visualize convert_from_bytes data flow Source: https://github.com/belval/pdf2image/blob/master/_autodocs/module-structure.md Step-by-step execution flow for converting PDF bytes to images. ```text convert_from_bytes(pdf_bytes, ...) ↓ [1] Create temporary file ↓ [2] Write bytes to temp file ↓ [3] Call convert_from_path() with temp file ↓ [4] Return images ↓ [5] Clean up temp file (finally block) ``` -------------------------------- ### Implement safe PDF conversion with exception handling Source: https://github.com/belval/pdf2image/blob/master/_autodocs/exceptions.md Wraps conversion and info retrieval in a try-except block to handle specific poppler-related errors gracefully. ```python from pdf2image import convert_from_path, pdfinfo_from_path from pdf2image.exceptions import ( PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError, PDFPopplerTimeoutError ) def safe_convert_pdf(pdf_path): try: # First check if we can read the PDF at all info = pdfinfo_from_path(pdf_path) pages = info.get("Pages", 0) print(f"PDF has {pages} pages") # Convert with timeout and strict checking images = convert_from_path( pdf_path, strict=True, timeout=60 ) return images except PDFInfoNotInstalledError: print("Error: poppler-utils is not installed") return None except PDFPageCountError: print("Error: Cannot read PDF (corrupted or invalid)") return None except PDFSyntaxError as e: print(f"Error: PDF has syntax errors: {e}") return None except PDFPopplerTimeoutError: print("Error: Conversion timed out") return None except Exception as e: print(f"Unexpected error: {e}") return None # Usage images = safe_convert_pdf("/path/to/document.pdf") if images: print(f"Successfully converted {len(images)} pages") ``` -------------------------------- ### Handle PDFPopplerTimeoutError Source: https://github.com/belval/pdf2image/blob/master/_autodocs/exceptions.md Example of catching a timeout exception during PDF conversion with a specified timeout duration. ```python from pdf2image import convert_from_path from pdf2image.exceptions import PDFPopplerTimeoutError try: # Convert with 30 second timeout images = convert_from_path("/path/to/large.pdf", timeout=30) except PDFPopplerTimeoutError: print("PDF conversion took too long and was cancelled") # Consider: # - Using output_folder to improve performance # - Increasing timeout value # - Converting pages in smaller batches # - Using fewer threads to reduce overhead ``` -------------------------------- ### Visualize convert_from_path data flow Source: https://github.com/belval/pdf2image/blob/master/_autodocs/module-structure.md Step-by-step execution flow for converting a PDF file path to images. ```text convert_from_path(pdf_path, ...) ↓ [1] Convert PurePath to string if needed ↓ [2] Get page count: pdfinfo_from_path() ↓ [3] Parse format: _parse_format(fmt, grayscale) ↓ [4] Determine if pdftocairo needed ↓ [5] Get poppler version: _get_poppler_version() ↓ [6] Create output_file generator if needed ↓ [7] Calculate page ranges per thread ↓ [8] For each thread: ├─ Build poppler command: _build_command() ├─ Spawn subprocess: Popen(args) └─ Communicate and handle timeout ↓ [9] Load results from output or parse buffer: ├─ If output_folder: _load_from_output_folder() └─ Else: parse_buffer_func(data) ↓ [10] Clean up temporary directories ↓ Return List[Image.Image] ``` -------------------------------- ### Convert PDF to images with pdf2image Source: https://github.com/belval/pdf2image/blob/master/_autodocs/00-START-HERE.md Demonstrates basic PDF conversion using convert_from_path and saving the resulting PIL Image object. ```python from pdf2image import convert_from_path # Convert PDF to images images = convert_from_path('/path/to/document.pdf') # Each image is a PIL.Image object first_page = images[0] first_page.save('/tmp/page1.png') ``` -------------------------------- ### Use default UUID-based output naming Source: https://github.com/belval/pdf2image/blob/master/_autodocs/configuration.md Demonstrates the default behavior where output files are named using random UUIDs. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output" # output_file defaults to uuid_generator() ) # Creates files like: 3a4f5b2c-1234-5678-abcd-ef0123456789.ppm ``` -------------------------------- ### Configure JPEG optimization options Source: https://github.com/belval/pdf2image/blob/master/_autodocs/configuration.md Sets compression parameters for JPEG output. Requires poppler version > 0.57. ```python jpegopt = { "quality": 85, # int: 0-100, default typically 85 "progressive": True, # bool: progressive JPEG format "optimize": True # bool: optimize JPEG compression } ``` -------------------------------- ### Optimize PDF conversion with multi-threading Source: https://github.com/belval/pdf2image/blob/master/_autodocs/advanced-usage-patterns.md Uses parallel processing and specific format settings to maximize conversion speed. Ensure the output folder is on a fast drive like an SSD for best results. ```python from pdf2image import convert_from_path import time def convert_fast(pdf_path): """Convert PDF with maximum performance.""" start = time.time() images = convert_from_path( pdf_path, output_folder="/tmp/pdf_pages", # Use SSD if available fmt="png", # Good balance of size/speed dpi=150, # Reasonable quality thread_count=4, # Parallel processing use_pdftocairo=True, # May be faster timeout=300 # 5 minute timeout ) elapsed = time.time() - start print(f"Converted {len(images)} pages in {elapsed:.2f}s") print(f"Average: {len(images)/elapsed:.2f} pages/sec") return images ``` -------------------------------- ### Get info for specific page range Source: https://github.com/belval/pdf2image/blob/master/_autodocs/api-reference-main-functions.md Limits the metadata extraction scope to a specific range of pages using first_page and last_page parameters. ```python from pdf2image import pdfinfo_from_path # Get info for only pages 1-10 info = pdfinfo_from_path( "/path/to/document.pdf", first_page=1, last_page=10 ) ``` -------------------------------- ### Enable transparency in PNG output Source: https://github.com/belval/pdf2image/blob/master/_autodocs/parsers.md Configuration for generating PNG images with transparent backgrounds. ```python images = convert_from_path( "/path/to/document.pdf", fmt="png", transparent=True # Transparent background instead of white ) ``` -------------------------------- ### Extract text from PDF using Tesseract OCR Source: https://github.com/belval/pdf2image/blob/master/_autodocs/advanced-usage-patterns.md Requires pytesseract installed. Uses a high DPI setting to improve OCR accuracy during image conversion. ```python from pdf2image import convert_from_path try: import pytesseract except ImportError: pytesseract = None def extract_text_from_pdf(pdf_path): """Convert PDF to text using OCR.""" if not pytesseract: print("Install pytesseract: pip install pytesseract") return None try: # Convert to images images = convert_from_path(pdf_path, dpi=300) # High DPI for better OCR all_text = {} for idx, image in enumerate(images): # Extract text from image text = pytesseract.image_to_string(image) all_text[f"page_{idx + 1}"] = text print(f"Extracted text from page {idx + 1}") return all_text except Exception as e: print(f"Error: {e}") return None # Usage text_data = extract_text_from_pdf("/path/to/document.pdf") if text_data: for page, text in text_data.items(): print(f"\n--- {page} ---") print(text[:200] + "..." if len(text) > 200 else text) ``` -------------------------------- ### Configure image size parameters Source: https://github.com/belval/pdf2image/blob/master/_autodocs/configuration.md Defines the various formats accepted by the size parameter to control output dimensions and aspect ratio. ```python # Single integer: fit to square, preserve aspect ratio size=400 # Result: image fit within 400x400 box # Single-element tuple: same as int size=(400,) # Two-element tuple with one None: preserve aspect ratio for that dimension size=(400, None) # Width 400, height proportional size=(None, 600) # Height 600, width proportional # Two-element tuple with both values: exact resize without aspect ratio preservation size=(500, 500) # Force to exactly 500x500 pixels # None: no resizing size=None # Use original PDF size adjusted only by DPI ``` -------------------------------- ### Quality-optimized conversion configuration Source: https://github.com/belval/pdf2image/blob/master/_autodocs/configuration.md Prioritize image fidelity by increasing DPI and using stable rendering settings. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", dpi=300, # High resolution fmt="png", # Lossless use_pdftocairo=False # More stable ) ``` -------------------------------- ### Batch convert PDFs with progress tracking in Python Source: https://github.com/belval/pdf2image/blob/master/_autodocs/advanced-usage-patterns.md Iterates through a directory of PDFs, retrieves page counts using pdfinfo_from_path, and converts each file while reporting progress. ```python from pdf2image import convert_from_path, pdfinfo_from_path import os def batch_convert(pdf_directory, output_directory): """Convert all PDFs in a directory.""" pdf_files = [f for f in os.listdir(pdf_directory) if f.endswith('.pdf')] for pdf_file in pdf_files: pdf_path = os.path.join(pdf_directory, pdf_file) # Get page count first try: info = pdfinfo_from_path(pdf_path) page_count = info["Pages"] print(f"Converting {pdf_file} ({page_count} pages)...") except Exception as e: print(f"Error getting info for {pdf_file}: {e}") continue # Convert try: images = convert_from_path( pdf_path, dpi=200, output_folder=os.path.join(output_directory, pdf_file.replace('.pdf', '')) ) print(f"✓ {pdf_file}: {len(images)} pages converted") except Exception as e: print(f"✗ {pdf_file}: {e}") batch_convert("/path/to/pdfs", "/path/to/output") ``` -------------------------------- ### Benchmark PDF conversion performance in Python Source: https://github.com/belval/pdf2image/blob/master/_autodocs/advanced-usage-patterns.md Iterates through various configurations of image formats and thread counts to calculate average conversion time and throughput. Requires a valid PDF file path to execute. ```python from pdf2image import convert_from_path import time import os def benchmark_conversion(pdf_path, iterations=3): """Benchmark different conversion settings.""" configs = [ {"fmt": "ppm", "dpi": 150, "thread_count": 1, "name": "PPM (single-threaded)"}, {"fmt": "ppm", "dpi": 150, "thread_count": 4, "name": "PPM (4 threads)"}, {"fmt": "jpeg", "dpi": 150, "thread_count": 1, "name": "JPEG (single-threaded)"}, {"fmt": "jpeg", "dpi": 150, "thread_count": 4, "name": "JPEG (4 threads)"}, {"fmt": "png", "dpi": 150, "thread_count": 1, "name": "PNG (single-threaded)"}, {"fmt": "png", "dpi": 150, "thread_count": 4, "name": "PNG (4 threads)"}, ] results = [] for config in configs: name = config.pop("name") times = [] for i in range(iterations): start = time.time() images = convert_from_path(pdf_path, **config) elapsed = time.time() - start times.append(elapsed) avg_time = sum(times) / len(times) results.append({ "config": name, "avg_time": avg_time, "pages_per_sec": len(images) / avg_time }) # Print results print("Performance Benchmark Results") print("="*60) print(f"{'Configuration':<30} {'Time (s)':<12} {'Pages/sec':<10}") print("-"*60) for result in sorted(results, key=lambda x: x["avg_time"]): print(f"{result['config']:<30} {result['avg_time']:>10.2f}s {result['pages_per_sec']:>9.2f}") fastest = min(results, key=lambda x: x["avg_time"]) print(f"\nFastest: {fastest['config']} ({fastest['avg_time']:.2f}s)") return results # Usage benchmark_conversion("/path/to/document.pdf") ``` -------------------------------- ### Dynamically select conversion format Source: https://github.com/belval/pdf2image/blob/master/_autodocs/advanced-usage-patterns.md Adjusts output format, DPI, and compression settings by inspecting file size and PDF metadata retrieved via pdfinfo_from_path. ```python from pdf2image import convert_from_path, pdfinfo_from_path def smart_convert(pdf_path): """Choose format based on PDF size and properties.""" import os # Get file size file_size_mb = os.path.getsize(pdf_path) / (1024 * 1024) # Get page count info = pdfinfo_from_path(pdf_path) page_count = info["Pages"] # Decide format if file_size_mb > 50 or page_count > 100: # Large PDF: use compression fmt = "jpeg" dpi = 150 jpegopt = {"quality": 80} print(f"Large PDF ({file_size_mb:.1f}MB, {page_count} pages) → JPEG") elif "Encrypted" in info and info["Encrypted"] == "yes": # Encrypted: use lossless fmt = "png" dpi = 200 jpegopt = None print("Encrypted PDF → PNG") else: # Default: balanced fmt = "png" dpi = 200 jpegopt = None print(f"Regular PDF ({page_count} pages) → PNG") # Convert images = convert_from_path( pdf_path, fmt=fmt, dpi=dpi, jpegopt=jpegopt if fmt == "jpeg" else None ) return images, fmt # Usage images, fmt = smart_convert("/path/to/document.pdf") print(f"Converted {len(images)} pages to {fmt.upper()}") ``` -------------------------------- ### Usage of JPEG conversion Source: https://github.com/belval/pdf2image/blob/master/_autodocs/parsers.md Demonstrates how to trigger the internal JPEG parser by setting the format to jpeg and providing options. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", fmt="jpeg", jpegopt={"quality": 85, "progressive": True} ) # Uses parse_buffer_to_jpeg internally ``` -------------------------------- ### Visualize pdfinfo_from_path data flow Source: https://github.com/belval/pdf2image/blob/master/_autodocs/module-structure.md Step-by-step execution flow for extracting PDF information. ```text pdfinfo_from_path(pdf_path, ...) ↓ [1] Build pdfinfo command with arguments ↓ [2] Set up environment with LD_LIBRARY_PATH ↓ [3] Spawn pdfinfo subprocess: Popen(command) ↓ [4] Wait for completion (with timeout if set) ↓ [5] Parse output into dictionary: ├─ Split by lines ├─ Split each line by ":" └─ Convert "Pages" to int ↓ [6] Validate "Pages" key present ↓ Return Dict[str, Union[int, str]] ``` -------------------------------- ### Perform multi-threaded PDF conversion Source: https://github.com/belval/pdf2image/blob/master/_autodocs/README.md Demonstrates how to use the thread_count parameter for concurrent processing. ```python images = convert_from_path( '/path/to/document.pdf', thread_count=4, # Safe multi-threading output_folder='/tmp' # Recommended for threads ) ``` -------------------------------- ### Optimize conversion speed Source: https://github.com/belval/pdf2image/blob/master/_autodocs/README.md Adjust DPI, format, thread count, and use pdftocairo to improve performance. ```python images = convert_from_path( '/path/to/document.pdf', dpi=150, # Lower DPI fmt='jpeg', # Compressed format thread_count=4, # Parallel processing use_pdftocairo=True # May be faster ) ``` -------------------------------- ### Implicit vs explicit generator usage Source: https://github.com/belval/pdf2image/blob/master/_autodocs/generators.md Demonstrates that passing a string to output_file is equivalent to using a counter_generator. ```python from pdf2image import convert_from_path # These two are equivalent: images1 = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file="page" # Converted to counter_generator("page") ) from pdf2image.generators import counter_generator images2 = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file=counter_generator(prefix="page") # Explicit ) # Both create: page0001.ppm, page0002.ppm, etc. ``` -------------------------------- ### Speed-optimized conversion configuration Source: https://github.com/belval/pdf2image/blob/master/_autodocs/configuration.md Configure for faster processing by utilizing parallel threads and optimized rendering backends. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/images", # Use disk I/O fmt="png", # Balanced size/speed thread_count=4, # Parallel processing use_pdftocairo=True, # May be faster dpi=150 # Lower DPI if acceptable ) ``` -------------------------------- ### Use counter_generator for output files Source: https://github.com/belval/pdf2image/blob/master/_autodocs/types.md Demonstrates using a counter generator to create numbered output filenames during PDF conversion. ```python from pdf2image import convert_from_path from pdf2image.generators import counter_generator gen = counter_generator(prefix="page_") images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp", output_file=gen ) ``` -------------------------------- ### Grayscale conversion with size constraints Source: https://github.com/belval/pdf2image/blob/master/_autodocs/api-reference-main-functions.md Converts to grayscale and resizes the output while maintaining aspect ratio. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", grayscale=True, size=400 # Fit to 400x400 box, preserving aspect ratio ) ``` -------------------------------- ### Convert PDF to PPM format Source: https://github.com/belval/pdf2image/blob/master/_autodocs/parsers.md Use PPM for lossless quality when file size and memory usage are not primary constraints. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", fmt="ppm" # Default ) ``` -------------------------------- ### Visualize Module Import Graph Source: https://github.com/belval/pdf2image/blob/master/_autodocs/module-structure.md A hierarchical representation of the internal module dependencies within the pdf2image package. ```text pdf2image/__init__.py └─→ pdf2image.py ├─→ generators.py ├─→ parsers.py │ └─→ PIL (Pillow) └─→ exceptions.py exceptions.py └─→ (no internal dependencies) generators.py ├─→ uuid (stdlib) └─→ threading (stdlib) parsers.py ├─→ io.BytesIO (stdlib) └─→ PIL.Image ``` -------------------------------- ### Define convert_from_path function signature Source: https://github.com/belval/pdf2image/blob/master/_autodocs/README.md Shows the type-hinted function signature for converting PDF files to images. ```python from typing import List, Union from pathlib import Path from PIL import Image def convert_from_path( pdf_path: Union[str, Path], dpi: int = 200, ... ) -> List[Image.Image]: ... ``` -------------------------------- ### Page range and DPI configuration Source: https://github.com/belval/pdf2image/blob/master/_autodocs/api-reference-main-functions.md Specifies a subset of pages to convert and sets the output resolution. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", first_page=5, last_page=10, dpi=300 # Higher quality ) # Returns pages 5-10 at 300 DPI ``` -------------------------------- ### Memory-optimized conversion configuration Source: https://github.com/belval/pdf2image/blob/master/_autodocs/configuration.md Use this configuration to process large PDF files by writing images directly to disk and minimizing memory footprint. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/large.pdf", output_folder="/tmp/images", # Write to disk fmt="jpeg", # Compressed format paths_only=True, # Don't load in memory thread_count=1 # Reduce overhead ) ``` -------------------------------- ### parse_buffer_to_png(data: bytes) -> List[Image.Image] Source: https://github.com/belval/pdf2image/blob/master/_autodocs/parsers.md Parses PNG format binary data into a list of PIL Image objects. ```APIDOC ## parse_buffer_to_png ### Description Parses PNG (Portable Network Graphics) format binary data into PIL Images. This function processes raw bytes, typically from pdftocairo output, by identifying IEND chunk markers to extract individual images. ### Signature `def parse_buffer_to_png(data: bytes) -> List[Image.Image]` ### Parameters - **data** (bytes) - Required - Raw PNG format bytes from pdftocairo output (multiple concatenated PNGs). ### Returns - **Type**: `List[Image.Image]` - A list of PIL Image objects decoded from the PNG data. ``` -------------------------------- ### Optimize memory for large PDFs Source: https://github.com/belval/pdf2image/blob/master/_autodocs/README.md Use a temporary directory and paths_only to avoid loading large files into memory. ```python from pdf2image import convert_from_path import tempfile with tempfile.TemporaryDirectory() as tmpdir: paths = convert_from_path( '/path/to/large.pdf', output_folder=tmpdir, fmt='jpeg', # Compressed paths_only=True # Don't load in memory ) # Process each image on-demand ``` -------------------------------- ### Convert PDF from HTTP response bytes Source: https://github.com/belval/pdf2image/blob/master/_autodocs/api-reference-main-functions.md Demonstrates converting PDF content retrieved directly from a web request. ```python from pdf2image import convert_from_bytes import requests response = requests.get("https://example.com/document.pdf") images = convert_from_bytes(response.content) ``` -------------------------------- ### Convert password-protected PDFs Source: https://github.com/belval/pdf2image/blob/master/_autodocs/README.md Provide the userpw argument to access secured PDF documents. ```python images = convert_from_path( '/path/to/secure.pdf', userpw='password' ) ``` -------------------------------- ### Specify output image format Source: https://github.com/belval/pdf2image/blob/master/docs/overview.md Change the default PPM format to other supported formats like JPEG, PNG, or TIFF. ```python images_from_path = convert_from_path("/home/user/example.pdf", fmt="jpeg") ``` -------------------------------- ### Implement JPEG stream splitting Source: https://github.com/belval/pdf2image/blob/master/_autodocs/parsers.md Shows the logic for splitting a concatenated JPEG byte stream using the end-of-image marker. ```python data.split(b"\xff\xd9")[:-1] # Remove empty last element # Then append marker back to each image before parsing ``` -------------------------------- ### Using Path Types in convert_from_path Source: https://github.com/belval/pdf2image/blob/master/_autodocs/types.md Demonstrates passing either a string or a pathlib.Path object to the convert_from_path function. ```python from pathlib import Path from pdf2image import convert_from_path # String path images = convert_from_path("/path/to/document.pdf") # PurePath object path = Path("/path/to/document.pdf") images = convert_from_path(path) # Works identically ``` -------------------------------- ### Clone pdf2image from source Source: https://github.com/belval/pdf2image/blob/master/docs/installation.md Use this method if you intend to modify the source code. ```bash git clone https://github.com/Belval/pdf2image ``` -------------------------------- ### Implement a Robust PDF Conversion Wrapper Source: https://github.com/belval/pdf2image/blob/master/_autodocs/advanced-usage-patterns.md A wrapper function that encapsulates pdf2image calls with specific exception handling for common library errors and configurable return behavior. ```python from pdf2image import convert_from_path, pdfinfo_from_path from pdf2image.exceptions import ( PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError, PDFPopplerTimeoutError ) from typing import Optional, List from PIL import Image def safe_convert_pdf( pdf_path: str, dpi: int = 200, fmt: str = "png", timeout: int = 60, on_error: str = "raise" # "raise", "return_none", "return_empty" ) -> Optional[List[Image.Image]]: """ Safely convert PDF with comprehensive error handling. Args: pdf_path: Path to PDF file dpi: Output DPI fmt: Output format timeout: Conversion timeout in seconds on_error: How to handle errors Returns: List of PIL Images or None on error (if on_error != "raise") """ try: # Validate file exists if not os.path.exists(pdf_path): raise FileNotFoundError(f"PDF not found: {pdf_path}") # Get page count to validate PDF info = pdfinfo_from_path(pdf_path, timeout=timeout) page_count = info["Pages"] print(f"Converting {page_count} pages...") # Convert images = convert_from_path( pdf_path, dpi=dpi, fmt=fmt, timeout=timeout, strict=False ) print(f"✓ Success: {len(images)} pages converted") return images except PDFInfoNotInstalledError: msg = "Error: poppler-utils not installed. Install with: apt-get install poppler-utils" except PDFPageCountError: msg = f"Error: Invalid PDF file: {pdf_path}" except PDFSyntaxError as e: msg = f"Error: PDF has syntax errors: {e}" except PDFPopplerTimeoutError: msg = f"Error: Conversion timeout after {timeout} seconds" except FileNotFoundError as e: msg = str(e) except Exception as e: msg = f"Unexpected error: {e}" # Handle error based on on_error parameter if on_error == "raise": raise RuntimeError(msg) elif on_error == "return_none": print(msg) return None elif on_error == "return_empty": print(msg) return [] # Usage import os images = safe_convert_pdf( "/path/to/document.pdf", dpi=200, timeout=120, on_error="return_empty" # Return empty list on error ) if images: print(f"Converted {len(images)} pages") else: print("Conversion failed") ``` -------------------------------- ### Implement Batch PDF Conversion with Error Recovery Source: https://github.com/belval/pdf2image/blob/master/_autodocs/advanced-usage-patterns.md Uses a try-except block to handle specific pdf2image exceptions during batch processing. Set strict=False in convert_from_path to allow processing despite syntax errors. ```python from pdf2image import convert_from_path from pdf2image.exceptions import ( PDFInfoNotInstalledError, PDFPageCountError, PDFSyntaxError, PDFPopplerTimeoutError ) import json import os def batch_convert_with_recovery(pdf_list, output_dir): """ Convert multiple PDFs with error recovery. Args: pdf_list: List of PDF file paths output_dir: Output directory for images Returns: Dict with conversion results and error log """ results = { "successful": [], "failed": [], "errors": {} } for idx, pdf_path in enumerate(pdf_list, 1): print(f"[{idx}/{len(pdf_list)}] Processing {os.path.basename(pdf_path)}...") try: pdf_name = os.path.splitext(os.path.basename(pdf_path))[0] output_folder = os.path.join(output_dir, pdf_name) os.makedirs(output_folder, exist_ok=True) # Convert with error handling images = convert_from_path( pdf_path, output_folder=output_folder, dpi=200, timeout=300, strict=False # Don't fail on syntax errors ) results["successful"].append({ "file": pdf_path, "pages": len(images), "output": output_folder }) print(f"✓ Success: {len(images)} pages") except PDFInfoNotInstalledError as e: results["failed"].append(pdf_path) results["errors"][pdf_path] = "poppler not installed" print(f"✗ Error: {e}") except PDFPageCountError as e: results["failed"].append(pdf_path) results["errors"][pdf_path] = "cannot read PDF" print(f"✗ Error: {e}") except PDFPopplerTimeoutError: results["failed"].append(pdf_path) results["errors"][pdf_path] = "timeout" print(f"✗ Error: Conversion timeout") except PDFSyntaxError as e: # Syntax errors are non-fatal with strict=False results["successful"].append({ "file": pdf_path, "pages": "unknown (syntax errors)", "output": output_folder }) results["errors"][pdf_path] = f"syntax errors: {e}" print(f"⚠ Syntax errors but processed anyway") except Exception as e: results["failed"].append(pdf_path) results["errors"][pdf_path] = str(e) print(f"✗ Unexpected error: {e}") # Summary print("\n" + "="*60) print(f"Results: {len(results['successful'])} successful, {len(results['failed'])} failed") # Save report report_path = os.path.join(output_dir, "conversion_report.json") with open(report_path, "w") as f: json.dump(results, f, indent=2) print(f"Report saved to: {report_path}") return results # Usage pdf_files = [ "/data/doc1.pdf", "/data/doc2.pdf", "/data/doc3.pdf" ] results = batch_convert_with_recovery(pdf_files, "/output/images") ``` -------------------------------- ### Accessing PDF Metadata Source: https://github.com/belval/pdf2image/blob/master/_autodocs/types.md Demonstrates how to retrieve and safely access fields from the PDF metadata dictionary. ```python from pdf2image import pdfinfo_from_path info = pdfinfo_from_path("/path/to/document.pdf") # Always safe to access Pages (converted to int) page_count = info["Pages"] # Other keys may be None or missing title = info.get("Title", "Unknown Title") author = info.get("Author", "Unknown Author") # Check encryption status is_encrypted = info.get("Encrypted") == "yes" ``` -------------------------------- ### Flask REST API Integration for PDF Conversion Source: https://github.com/belval/pdf2image/blob/master/_autodocs/advanced-usage-patterns.md Demonstrates handling PDF uploads, converting them to images with specific DPI and format settings, and returning the result via HTTP. Includes error handling for common pdf2image exceptions. ```python from flask import Flask, request, jsonify, send_file from pdf2image import convert_from_bytes from pdf2image.exceptions import ( PDFPageCountError, PDFPopplerTimeoutError, PDFSyntaxError ) import io import tempfile import os app = Flask(__name__) @app.route('/convert', methods=['POST']) def convert_pdf(): """Convert uploaded PDF to images.""" if 'pdf' not in request.files: return jsonify({"error": "No PDF file"}), 400 pdf_file = request.files['pdf'] dpi = request.args.get('dpi', 200, type=int) fmt = request.args.get('format', 'jpeg', type=str) try: # Read uploaded file pdf_bytes = pdf_file.read() # Convert with timeout images = convert_from_bytes( pdf_bytes, dpi=dpi, fmt=fmt, timeout=30 # 30 second timeout for HTTP ) # Return first page as image if images: img_bytes = io.BytesIO() images[0].save(img_bytes, format=fmt.upper()) img_bytes.seek(0) return send_file( img_bytes, mimetype=f'image/{fmt}', as_attachment=True, download_name='page1.jpg' ) else: return jsonify({"error": "No pages converted"}), 400 except PDFPageCountError as e: return jsonify({"error": f"Invalid PDF: {e}"}), 400 except PDFPopplerTimeoutError: return jsonify({"error": "Conversion timeout"}), 504 except PDFSyntaxError as e: return jsonify({"error": f"PDF syntax error: {e}"}), 400 except Exception as e: return jsonify({"error": str(e)}), 500 @app.route('/preview/', methods=['GET']) def preview_pdf(filename): """Preview first page of a stored PDF.""" pdf_path = os.path.join('/uploads', filename) if not os.path.exists(pdf_path): return jsonify({"error": "File not found"}), 404 try: images = convert_from_path( pdf_path, dpi=100, # Lower DPI for preview timeout=10 ) if images: img_bytes = io.BytesIO() images[0].save(img_bytes, format='JPEG') img_bytes.seek(0) return send_file(img_bytes, mimetype='image/jpeg') except Exception as e: return jsonify({"error": str(e)}), 500 if __name__ == '__main__': app.run(debug=False) ``` -------------------------------- ### Package Directory Structure Source: https://github.com/belval/pdf2image/blob/master/_autodocs/module-structure.md Visual representation of the file hierarchy within the pdf2image package. ```text pdf2image/ ├── __init__.py # Public API exports ├── pdf2image.py # Main conversion functions ├── exceptions.py # Custom exception classes ├── generators.py # Filename generators ├── parsers.py # Format-specific parsers └── py.typed # Type hints marker ``` -------------------------------- ### Use string-based output naming Source: https://github.com/belval/pdf2image/blob/master/_autodocs/configuration.md Automatically converts a string to a counter_generator for sequential file naming. ```python from pdf2image import convert_from_path images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file="page" # Becomes: page0001, page0002, etc. ) ``` -------------------------------- ### Basic PDF conversion Source: https://github.com/belval/pdf2image/blob/master/_autodocs/api-reference-main-functions.md Converts a PDF file into a list of PIL Image objects. ```python from pdf2image import convert_from_path images = convert_from_path("/path/to/document.pdf") # images is a list of PIL.Image objects, one per page first_page_image = images[0] first_page_image.save("/tmp/page0.png") ``` -------------------------------- ### Use custom output file generators Source: https://github.com/belval/pdf2image/blob/master/_autodocs/configuration.md Provides full control over file naming using custom generator objects, including thread-safe options. ```python from pdf2image import convert_from_path from pdf2image.generators import counter_generator, ThreadSafeGenerator # Custom counter generator with prefix and suffix gen = counter_generator(prefix="document_", suffix="_page", padding_goal=3) images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file=gen ) # Creates files like: document_001_page.ppm, document_002_page.ppm, etc. # For thread-safe generation when using multiple threads gen = ThreadSafeGenerator(counter_generator(prefix="page_")) images = convert_from_path( "/path/to/document.pdf", output_folder="/tmp/output", output_file=gen, thread_count=4 # Safe with multiple threads ) ```