tomo2chin2 commited on
Commit
dd6c350
·
verified ·
1 Parent(s): 445dd97

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +123 -0
app.py ADDED
@@ -0,0 +1,123 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import gradio as gr
3
+ import fitz # PyMuPDF
4
+ from pathlib import Path
5
+ import google.generativeai as genai
6
+ import tempfile
7
+ import base64
8
+ from concurrent.futures import ThreadPoolExecutor
9
+
10
+ # Gemini APIの設定
11
+ GOOGLE_API_KEY = "あなたのGemini APIキーをここに入力"
12
+ genai.configure(api_key=GOOGLE_API_KEY)
13
+
14
+ def split_pdf(pdf_path, output_dir, pages_per_chunk=5):
15
+ """PDFを指定ページ数ごとに分割する関数"""
16
+ pdf_document = fitz.open(pdf_path)
17
+ total_pages = len(pdf_document)
18
+
19
+ split_pdfs = []
20
+
21
+ for start_page in range(0, total_pages, pages_per_chunk):
22
+ end_page = min(start_page + pages_per_chunk - 1, total_pages - 1)
23
+
24
+ # 新しいPDFドキュメントを作成
25
+ output_pdf = fitz.open()
26
+
27
+ # 指定範囲のページを新しいPDFに追加
28
+ for page_num in range(start_page, end_page + 1):
29
+ output_pdf.insert_pdf(pdf_document, from_page=page_num, to_page=page_num)
30
+
31
+ # 分割したPDFを保存
32
+ output_path = os.path.join(output_dir, f"split_{start_page+1}_to_{end_page+1}.pdf")
33
+ output_pdf.save(output_path)
34
+ output_pdf.close()
35
+
36
+ split_pdfs.append(output_path)
37
+
38
+ pdf_document.close()
39
+ return split_pdfs
40
+
41
+ def encode_pdf_to_base64(pdf_path):
42
+ """PDFファイルをbase64エンコードする関数"""
43
+ with open(pdf_path, "rb") as pdf_file:
44
+ return base64.b64encode(pdf_file.read()).decode('utf-8')
45
+
46
+ def ocr_pdf_with_gemini(pdf_path):
47
+ """GeminiモデルでPDFをOCRしてマークダウンに変換する関数"""
48
+ # PDFをbase64エンコード
49
+ pdf_base64 = encode_pdf_to_base64(pdf_path)
50
+
51
+ # Geminiモデルの設定
52
+ model = genai.GenerativeModel('gemini-2.0-flash')
53
+
54
+ # プロンプトの設定
55
+ prompt = """
56
+ このPDFに含まれるテキストをOCRで読み取り、整形されたマークダウン形式に変換してください。
57
+ 以下の点に注意してください:
58
+ - 見出しは適切なマークダウン見出し記法(#, ##, ###など)を使用
59
+ - 箇条書きリストは適切に変換
60
+ - 表はマークダウン表形式に変換
61
+ - 段落構造を維持
62
+ - 余分な改行やスペースは整理
63
+ - 画像の内容は[画像: 内容の説明]と表記
64
+ """
65
+
66
+ # PDFをGeminiに送信
67
+ response = model.generate_content([
68
+ prompt,
69
+ {"mime_type": "application/pdf", "data": pdf_base64}
70
+ ])
71
+
72
+ # 結果を返す
73
+ return response.text
74
+
75
+ def process_pdf(pdf_file):
76
+ """PDFファイルを処理するメイン関数"""
77
+ # 一時ディレクトリを作成
78
+ with tempfile.TemporaryDirectory() as temp_dir:
79
+ # アップロードされたPDFを一時ファイルとして保存
80
+ temp_pdf_path = os.path.join(temp_dir, "uploaded.pdf")
81
+ with open(temp_pdf_path, "wb") as f:
82
+ f.write(pdf_file)
83
+
84
+ # PDFを分割
85
+ split_pdf_paths = split_pdf(temp_pdf_path, temp_dir)
86
+
87
+ # 並列処理でOCR変換
88
+ markdown_results = []
89
+ with ThreadPoolExecutor() as executor:
90
+ markdown_results = list(executor.map(ocr_pdf_with_gemini, split_pdf_paths))
91
+
92
+ # 結果を結合
93
+ combined_markdown = "\n\n".join(markdown_results)
94
+
95
+ return combined_markdown
96
+
97
+ # Gradioインターフェースの作成
98
+ def create_interface():
99
+ with gr.Blocks() as demo:
100
+ gr.Markdown("# PDF OCR & マークダウン変換ツール")
101
+ gr.Markdown("PDFをアップロードすると、OCRでテキストを抽出しマークダウン形式に変換します。")
102
+
103
+ with gr.Row():
104
+ pdf_input = gr.File(label="PDFファイルをアップロード", file_types=[".pdf"])
105
+
106
+ with gr.Row():
107
+ convert_btn = gr.Button("変換開始")
108
+
109
+ with gr.Row():
110
+ markdown_output = gr.Markdown(label="変換結果")
111
+
112
+ convert_btn.click(
113
+ fn=process_pdf,
114
+ inputs=pdf_input,
115
+ outputs=markdown_output
116
+ )
117
+
118
+ return demo
119
+
120
+ # アプリの起動
121
+ if __name__ == "__main__":
122
+ demo = create_interface()
123
+ demo.launch()