soiz1 commited on
Commit
99ee49c
·
verified ·
1 Parent(s): 308d902

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +39 -124
app.py CHANGED
@@ -1,135 +1,50 @@
1
  import gradio as gr
2
- import tempfile
3
  from pdf2image import convert_from_path
4
- import fitz # PyMuPDF
5
- import cv2
6
- import numpy as np
7
-
8
- # ========== 解析ロジック関数 ==========
9
-
10
- def estimate_blurriness(pil_image):
11
- """
12
- ぼけ度を推定(Laplacian分散)
13
- 値が小さいほどぼけている
14
- """
15
- gray = np.array(pil_image.convert('L'))
16
- return cv2.Laplacian(gray, cv2.CV_64F).var()
17
-
18
- def estimate_contrast(pil_image):
19
- """
20
- コントラストを推定(標準偏差)
21
- 値が小さいほどグレーでのっぺり
22
- """
23
- gray = np.array(pil_image.convert('L'))
24
- return gray.std()
25
-
26
- def analyze_pdf(pdf_file):
27
- """
28
- アップロードされたPDFの各ページを画像に変換し
29
- - 画像サイズ
30
- - 総ピクセル数
31
- - ぼけ度
32
- - コントラスト
33
- - 推定DPI
34
- などをもとにAudiverisでの利用適性を判定
35
- """
36
- MAX_PIXELS_AUDIVERIS = 20_000_000
37
- results = []
38
- overall_rating = "OK"
39
-
40
- try:
41
- with tempfile.TemporaryDirectory() as tmpdir:
42
- # PDF → 画像変換
43
- images = convert_from_path(pdf_file.name, dpi=300, output_folder=tmpdir)
44
- doc = fitz.open(pdf_file.name)
45
 
46
- dpi_infos = []
47
-
48
- for i, (img, page) in enumerate(zip(images, doc)):
49
- width, height = img.size
50
- total_pixels = width * height
51
- reasons = []
52
- page_rating = "OK"
53
-
54
- # Audiverisのピクセル上限チェック
55
- if total_pixels > MAX_PIXELS_AUDIVERIS:
56
- page_rating = "非推奨(画像が大きすぎる)"
57
- reasons.append(f"総ピクセル数 {total_pixels:,} > 20,000,000")
58
-
59
- # 解像度チェック
60
- if width < 1000 or height < 1000 and "非推奨" not in page_rating:
61
- page_rating = "非推奨(解像度が小さい)"
62
- reasons.append("幅または高さが1000px未満")
63
- elif width < 1500 or height < 1500 and page_rating == "OK":
64
- page_rating = "注意(やや低め)"
65
-
66
- # ぼけ度チェック
67
- blur_score = estimate_blurriness(img)
68
- if blur_score < 30 and "非推奨" not in page_rating:
69
- page_rating = "非推奨(ぼけている)"
70
- reasons.append(f"ぼけ度={blur_score:.1f}")
71
 
72
- # コントラストチェック
73
- contrast_score = estimate_contrast(img)
74
- if contrast_score < 30 and "非推奨" not in page_rating:
75
- page_rating = "非推奨(コントラストが低い)"
76
- reasons.append(f"コントラスト={contrast_score:.1f}")
77
 
78
- # DPI情報
79
- rect = page.rect
80
- width_pt = rect.width
81
- height_pt = rect.height
82
- dpi_x = width / (width_pt / 72)
83
- dpi_y = height / (height_pt / 72)
84
- dpi_infos.append(f"ページ{i+1}推定DPI: {dpi_x:.1f}x{dpi_y:.1f}")
85
-
86
- # 理由をまとめる
87
- reasons_str = "; ".join(reasons) if reasons else "条件クリア"
88
-
89
- # ページ結果
90
- results.append(
91
- f"ページ{i+1}: {width}x{height}px / ピクセル数={total_pixels:,} / "
92
- f"ぼけ度={blur_score:.1f} / コントラスト={contrast_score:.1f} → {page_rating} ({reasons_str})"
93
- )
94
-
95
- # 総合評価を更新
96
- if "非推奨" in page_rating:
97
- overall_rating = "非推奨"
98
- elif "注意" in page_rating and overall_rating == "OK":
99
- overall_rating = "注意"
100
-
101
- # まとめテキスト
102
- result_text = "\n".join(results + [""] + dpi_infos)
103
- result_text += f"\n\n総合評価: {overall_rating}"
104
-
105
- # 改善提案
106
- if overall_rating == "非推奨":
107
- result_text += "\n\n推奨対策: スキャン解像度を下げる・画像を縮小するなどして、ファイルサイズや画質を調整してください。"
108
-
109
- return result_text, overall_rating
110
-
111
- except Exception as e:
112
- return f"処理中にエラーが発生しました: {str(e)}", "エラー"
113
-
114
- # ========== Gradio UI部分 ==========
115
 
116
  with gr.Blocks() as demo:
117
- gr.Markdown("# 🎼 Audiveris適性チェック(非公式・推定)")
118
  gr.Markdown(
119
- """
120
- PDFをアップロードすると、ページごとの画像サイズ、ピクセル数、ぼけ度、コントラストを分析し、
121
- Audiverisで使用可能かを「OK / 注意 / 非推奨」で推定します。
122
- """
123
  )
124
-
125
  with gr.Row():
126
- pdf_input = gr.File(label="PDFファイル")
127
- analyze_button = gr.Button("判定")
128
-
129
- result_output = gr.Textbox(label="詳細結果", lines=20)
130
- rating_output = gr.Textbox(label="総合評価")
131
-
132
- analyze_button.click(analyze_pdf, inputs=pdf_input, outputs=[result_output, rating_output])
133
 
134
- if __name__ == "__main__":
135
- demo.launch()
 
1
  import gradio as gr
 
2
  from pdf2image import convert_from_path
3
+ from PIL import Image
4
+ import img2pdf
5
+ import tempfile
6
+ import os
7
+
8
+ def downscale_pdf(pdf_file, max_width=3000, dpi=150):
9
+ with tempfile.TemporaryDirectory() as tmpdir:
10
+ # ステップ 1: PDF → 画像
11
+ images = convert_from_path(pdf_file.name, dpi=300, fmt='jpeg', output_folder=tmpdir)
12
+
13
+ downscaled_images = []
14
+ for i, img in enumerate(images):
15
+ w, h = img.size
16
+ total_px = w * h
17
+ print(f"Original Page {i+1}: {w}x{h} = {total_px}")
18
+
19
+ # サイズ制限
20
+ if w > max_width:
21
+ ratio = max_width / w
22
+ new_w = int(w * ratio)
23
+ new_h = int(h * ratio)
24
+ img = img.resize((new_w, new_h), Image.LANCZOS)
25
+ print(f"Downscaled Page {i+1}: {new_w}x{new_h} = {new_w * new_h}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
26
 
27
+ tmp_image_path = os.path.join(tmpdir, f"page_{i+1}.jpg")
28
+ img.save(tmp_image_path, "JPEG", quality=95)
29
+ downscaled_images.append(tmp_image_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
30
 
31
+ # ステップ 2: 画像 → PDF
32
+ output_pdf_path = os.path.join(tmpdir, "downscaled.pdf")
33
+ with open(output_pdf_path, "wb") as f:
34
+ f.write(img2pdf.convert(downscaled_images))
 
35
 
36
+ return output_pdf_path
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
37
 
38
  with gr.Blocks() as demo:
39
+ gr.Markdown("## PDFダウンサイザー for Audiveris")
40
  gr.Markdown(
41
+ "PDFをアップロードすると、ページ画像を縮小してAudiveris向けに最適化したPDFを生成します。"
 
 
 
42
  )
 
43
  with gr.Row():
44
+ pdf_input = gr.File(label="PDFファイルをアップロード")
45
+ pdf_output = gr.File(label="変換後PDF")
46
+
47
+ convert_button = gr.Button("変換してダウンロード")
48
+ convert_button.click(fn=downscale_pdf, inputs=pdf_input, outputs=pdf_output)
 
 
49
 
50
+ demo.launch()