File size: 2,130 Bytes
904d924
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
47
48
49
50
51
import fitz  # PyMuPDF
from PIL import Image
import io
import json

def build_searchable_pdf(image_list, ocr_results_list, output_path="searchable.pdf"):
    doc = fitz.open()

    for i, (image, ocr_data) in enumerate(zip(image_list, ocr_results_list)):
        # Convert PIL Image to bytes for embedding
        img_byte_arr = io.BytesIO()
        image.save(img_byte_arr, format='PNG') # Use PNG for lossless quality
        img_bytes = img_byte_arr.getvalue()

        # Create a new page with the original image dimensions
        img_width, img_height = image.size
        page = doc.new_page(width=img_width, height=img_height)

        # Embed the original image as the background
        rect = fitz.Rect(0, 0, img_width, img_height)
        page.insert_image(rect, stream=img_bytes)

        # Directly use OCR results (now assumed to be a dictionary)
        if not isinstance(ocr_data, dict):
            print(f"Warning: OCR result for page {i} is not a dictionary. Skipping text layer.")
            continue

        # Place invisible text at exact coordinates
        for word_data in ocr_data.get('words', []):
            word_text = word_data.get('text')
            bbox = word_data.get('bbox') # [x0, y0, x1, y1]

            if word_text and bbox and len(bbox) == 4:
                # PyMuPDF uses (x0, y0, x1, y1) for rects
                text_rect = fitz.Rect(bbox[0], bbox[1], bbox[2], bbox[3])
                
                # A simple approach to estimate font size based on bbox height
                font_size = max(1, bbox[3] - bbox[1]) 

                # Insert text, making it invisible (render_mode=3)
                # You might need to adjust text_rect coordinates or font_size for better alignment
                page.insert_textbox(text_rect, word_text, 
                                    fontsize=font_size, 
                                    render_mode=3,  # Invisible text
                                    fill=None) # No fill color needed for invisible text

    doc.save(output_path)
    doc.close()

    return output_path