soiz1 commited on
Commit
49acc9d
·
verified ·
1 Parent(s): 98715d0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +47 -34
app.py CHANGED
@@ -1,40 +1,53 @@
1
  import gradio as gr
2
- import subprocess
3
- import os
4
  import tempfile
 
 
 
 
5
 
6
- def rasterize_with_pdftoppm(input_pdf):
7
  with tempfile.TemporaryDirectory() as tmpdir:
8
- output_prefix = os.path.join(tmpdir, "page")
9
- cmd1 = ["pdftoppm", "-png", "-r", "150", input_pdf, output_prefix]
10
- res1 = subprocess.run(cmd1, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
11
- if res1.returncode != 0:
12
- return f"pdftoppm変換エラー: {res1.stderr.decode()}", None, None
13
-
14
- # PNGファイル一覧取得
15
- png_files = sorted([os.path.join(tmpdir, f) for f in os.listdir(tmpdir) if f.endswith(".png")])
16
- if not png_files:
17
- return "PNG変換に失敗しました", None, None
18
-
19
- # PNG→PDF変換(ImageMagickのconvertが使えなければpypdfで合成も可能)
20
- output_pdf = os.path.join(tmpdir, "output_rasterized.pdf")
21
- cmd2 = ["convert"] + png_files + [output_pdf]
22
- res2 = subprocess.run(cmd2, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
23
- if res2.returncode != 0:
24
- return f"PDF作成エラー: {res2.stderr.decode()}", None, None
25
-
26
- size_bytes = os.path.getsize(output_pdf)
27
- size_kb = size_bytes / 1024
28
- size_str = f"{size_bytes} bytes ({size_kb:.1f} KB)"
29
-
30
- return "pdftoppmでラスタライズ完了", output_pdf, size_str
31
-
32
- demo = gr.Interface(
33
- fn=rasterize_with_pdftoppm,
34
- inputs=gr.File(file_types=[".pdf"]),
35
- outputs=[gr.Text(), gr.File(), gr.Text()],
36
- title="PDFをpdftoppmでラスタライズ",
37
- description="pdftoppmでPDFをPNGに変換し再度PDF化します。"
38
- )
 
 
 
 
 
 
 
 
 
 
 
39
 
40
  demo.launch()
 
1
  import gradio as gr
 
 
2
  import tempfile
3
+ from pdf2image import convert_from_path
4
+ from PIL import Image
5
+ import img2pdf
6
+ import os
7
 
8
+ def downscale_pdf(pdf_file, dpi=150, max_width=1500):
9
  with tempfile.TemporaryDirectory() as tmpdir:
10
+ # ステップ 1: PDF → 画像(dpiを指定)
11
+ images = convert_from_path(pdf_file.name, dpi=dpi, output_folder=tmpdir)
12
+
13
+ downscaled_paths = []
14
+
15
+ for i, img in enumerate(images):
16
+ # ステップ 2: サイズを制限
17
+ w, h = img.size
18
+ if w > max_width:
19
+ new_h = int(h * max_width / w)
20
+ img = img.resize((max_width, new_h), Image.LANCZOS)
21
+
22
+ # 一時保存
23
+ img_path = os.path.join(tmpdir, f"page_{i}.jpg")
24
+ img.save(img_path, "JPEG", quality=85)
25
+ downscaled_paths.append(img_path)
26
+
27
+ # ステップ 3: 画像をPDFに再結合
28
+ output_pdf_path = os.path.join(tmpdir, "downscaled.pdf")
29
+ with open(output_pdf_path, "wb") as f_out:
30
+ f_out.write(img2pdf.convert(downscaled_paths))
31
+
32
+ # 返却
33
+ return output_pdf_path
34
+
35
+ with gr.Blocks() as demo:
36
+ gr.Markdown("# PDF 解像度ダウンサイザー\nPDFのページ画像を縮小して容量を減らします。")
37
+ with gr.Row():
38
+ with gr.Column():
39
+ pdf_input = gr.File(label="入力PDF", file_types=[".pdf"])
40
+ dpi_input = gr.Slider(72, 300, value=150, step=1, label="変換DPI")
41
+ width_input = gr.Slider(500, 3000, value=1500, step=50, label="最大幅(px)")
42
+ convert_button = gr.Button("変換")
43
+
44
+ with gr.Column():
45
+ pdf_output = gr.File(label="出力PDF")
46
+
47
+ convert_button.click(
48
+ fn=downscale_pdf,
49
+ inputs=[pdf_input, dpi_input, width_input],
50
+ outputs=pdf_output
51
+ )
52
 
53
  demo.launch()