File size: 1,498 Bytes
67e7598
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
import fitz  # PyMuPDF
from PIL import Image
import io

def get_pdf_page_count(pdf_bytes: bytes) -> int:
    """Return the total number of pages in the PDF bytes."""
    try:
        doc = fitz.open(stream=pdf_bytes, filetype="pdf")
        return len(doc)
    except Exception as e:
        print(f"Error reading PDF page count: {e}")
        return 0

def pdf_page_to_pil(pdf_bytes: bytes, page_index: int, dpi: int = 150) -> Image.Image:
    """Render a PDF page to a high-DPI RGB PIL Image."""
    doc = fitz.open(stream=pdf_bytes, filetype="pdf")
    page = doc.load_page(page_index)
    
    # Scale matrix for high quality DPI rendering (72 is default PDF DPI)
    zoom = dpi / 72.0
    mat = fitz.Matrix(zoom, zoom)
    
    pix = page.get_pixmap(matrix=mat)
    png_bytes = pix.tobytes("png")
    
    return Image.open(io.BytesIO(png_bytes)).convert("RGB")

def compile_images_to_pdf(pil_images: list) -> bytes:
    """Compile a list of PIL Images into a single PDF bytes object."""
    doc = fitz.open()
    for pil_img in pil_images:
        # Save PIL image as a single-page PDF in a bytes buffer
        pdf_buffer = io.BytesIO()
        pil_img.save(pdf_buffer, format="PDF")
        pdf_buffer.seek(0)
        
        # Open single page PDF and insert into compiled document
        page_doc = fitz.open("pdf", pdf_buffer.read())
        doc.insert_pdf(page_doc)
        
    out_buffer = io.BytesIO()
    doc.save(out_buffer)
    doc.close()
    
    return out_buffer.getvalue()