File size: 2,688 Bytes
8747881
c54ad31
 
8747881
c760c3b
 
c54ad31
c760c3b
c54ad31
 
 
 
 
 
 
 
12f2682
 
c54ad31
 
 
 
12f2682
c54ad31
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12f2682
c54ad31
 
 
 
 
 
 
8747881
2bcdb19
3de5753
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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
import gradio as gr
import fitz
import csv
import tempfile
import os

def analyze_pdf(file_obj):
    if file_obj is None:
        return "ファイルをアップロードしてください", None
    
    doc = fitz.open(file_obj.name)
    temp_dir = tempfile.mkdtemp()
    
    results = []
    full_text_order = []
    
    for page_num in range(len(doc)):
        page = doc[page_num]
        blocks = page.get_text("rawdict")["blocks"]
        char_idx = 0
        for b_idx, block in enumerate(blocks):
            if "lines" not in block:
                continue
            for l_idx, line in enumerate(block["lines"]):
                for s_idx, span in line["spans"]:
                    font = span.get("font", "")
                    for char in span["chars"]:
                        c = char["c"]
                        bbox = char["bbox"]
                        results.append({
                            "index": char_idx,
                            "char": c,
                            "x0": round(bbox[0], 2),
                            "y0": round(bbox[1], 2),
                            "x1": round(bbox[2], 2),
                            "y1": round(bbox[3], 2),
                            "block": b_idx,
                            "line": l_idx,
                            "span": s_idx,
                            "font": font,
                        })
                        full_text_order.append(c)
                        char_idx += 1
    
    doc.close()
    
    csv_path = os.path.join(temp_dir, "char_order.csv")
    with open(csv_path, "w", encoding="utf-8-sig", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=["index","char","x0","y0","x1","y1","block","line","span","font"])
        writer.writeheader()
        writer.writerows(results)
    
    # 最初の200文字を表示
    preview = "".join(full_text_order[:500])
    summary = f"総文字数: {len(full_text_order)}\n\n抽出順テキスト(先頭500文字):\n{preview}"
    
    return summary, csv_path

with gr.Blocks(title="PDF文字順序解析") as demo:
    gr.Markdown("## PDF文字抽出順序の解析")
    gr.Markdown("PDFをアップロードすると、内部のテキスト抽出順序をCSVで出力します")
    
    with gr.Row():
        file_input = gr.File(label="PDFファイル", file_types=[".pdf"], type="file")
    
    run_btn = gr.Button("解析実行", variant="primary")
    summary_box = gr.Textbox(label="結果サマリ", lines=15)
    csv_output = gr.File(label="文字順序CSV")
    
    run_btn.click(fn=analyze_pdf, inputs=[file_input], outputs=[summary_box, csv_output])

if __name__ == "__main__":
    demo.launch()