naohiro701 commited on
Commit
b58ebe5
·
verified ·
1 Parent(s): e1521b4

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +64 -65
app.py CHANGED
@@ -1,81 +1,77 @@
1
  import streamlit as st
2
- from pdf2image import convert_from_bytes
3
- from PIL import Image
4
  import io
5
  import zipfile
6
- import sys
7
- import os
8
 
9
- def convert_pdf_to_images(pdf_byte_data, dpi_value, poppler_path_value):
10
  """
11
- Convert a PDF file in bytes to a list of PIL images using pdf2image.
 
12
  Args:
13
- pdf_byte_data (bytes): PDF file in memory
14
- dpi_value (int): DPI setting for the conversion
15
- poppler_path_value (str): poppler path (Windows user only)
16
  Returns:
17
- list: A list of PIL Image objects
18
  """
19
- images_list = convert_from_bytes(
20
- pdf_byte_data,
21
- dpi=dpi_value,
22
- poppler_path=poppler_path_value if poppler_path_value else None
23
- )
 
 
 
 
 
 
 
 
24
  return images_list
25
 
26
  def create_zip_from_images(images_list):
27
  """
28
- Create an in-memory ZIP file from a list of PIL images.
29
- Each image is saved as a PNG in the ZIP file.
 
 
 
 
 
30
  """
31
- zip_buf = io.BytesIO()
32
- with zipfile.ZipFile(zip_buf, "w", zipfile.ZIP_DEFLATED) as zf:
33
- for idx, single_image in enumerate(images_list):
34
- img_buf = io.BytesIO()
35
- single_image.save(img_buf, format='PNG')
36
- img_buf.seek(0)
37
- zf.writestr(f"page_{idx+1}.png", img_buf.read())
38
- zip_buf.seek(0)
39
- return zip_buf
40
 
41
- # Streamlit App
42
- st.title("PDFを高画質PNG画像に変換")
43
- st.write(
44
  """
45
- このアプリケーションでは、アップロードしたPDFファイルを高解像度(例:1000 dpi)のPNG画像に変換します。
46
- 変換後、各ページの画像をダウンロード可能なZIPファイルとして提供します。
47
  """
48
- )
49
-
50
- uploaded_file = st.file_uploader("PDFファイルをアップロードしてください", type=["pdf"])
51
-
52
- if uploaded_file is not None:
53
- # DPIの設定
54
- dpi = st.slider("解像度(dpi)を選択してください", min_value=100, max_value=3000, value=1000, step=100)
55
 
56
- # Windows向けのPopplerパス入力 (Mac/LinuxなどPOPPLERがPATHに通っている環境なら不要)
57
- poppler_path_input = None
58
- if sys.platform.startswith("win"):
59
- poppler_path_input = st.text_input(
60
- "Popplerのパスを入力してください(Windowsユーザーのみ)",
61
- value="" # 例: "C:\\poppler-xx\\bin"
62
- )
63
- if poppler_path_input and not os.path.exists(poppler_path_input):
64
- st.warning("指定されたPopplerのパスが存在しません。正しいパスを入力してください。")
65
 
66
- if st.button("変換開始"):
67
- try:
68
- with st.spinner("PDFを画像に変換中..."):
69
- # PDF→画像へ変換
70
- images_converted = convert_pdf_to_images(
71
- uploaded_file.read(),
72
- dpi_value=dpi,
73
- poppler_path_value=poppler_path_input
74
- )
75
-
76
- # ZIPファ��ル作成
77
- zip_file_bytes = create_zip_from_images(images_converted)
78
 
 
 
 
 
 
 
79
  st.success("変換が完了しました!")
80
  st.download_button(
81
  label="ZIPファイルをダウンロード",
@@ -84,10 +80,13 @@ if uploaded_file is not None:
84
  mime="application/zip"
85
  )
86
 
87
- # 各ページの画像を表示(オプション)
88
- st.write("変換された画像:")
89
- for i, image in enumerate(images_converted):
90
- st.image(image, caption=f"ページ {i+1}", use_column_width=True)
 
 
 
91
 
92
- except Exception as e:
93
- st.error(f"変換中にエラーが発生しました: {e}")
 
1
  import streamlit as st
2
+ import fitz # PyMuPDF
 
3
  import io
4
  import zipfile
5
+ from PIL import Image
 
6
 
7
+ def convert_pdf_to_images(pdf_data, dpi_value):
8
  """
9
+ Convert each page of a PDF into a list of PIL.Image objects using PyMuPDF.
10
+
11
  Args:
12
+ pdf_data (bytes): PDF content in bytes
13
+ dpi_value (int): DPI (resolution) for rasterization
14
+
15
  Returns:
16
+ list: A list of PIL.Image objects representing each page
17
  """
18
+ images_list = []
19
+ # open PDF from memory
20
+ with fitz.open(stream=pdf_data, filetype="pdf") as doc:
21
+ for page_index in range(len(doc)):
22
+ page = doc.load_page(page_index)
23
+ # `matrix = fitz.Matrix(scale_x, scale_y)` で拡大率を指定
24
+ # DPI は (72 * scale_x, 72 * scale_y) になるイメージ
25
+ scale_val = dpi_value / 72.0 # PyMuPDF は 72dpi 基準
26
+ matrix = fitz.Matrix(scale_val, scale_val)
27
+ pix = page.get_pixmap(matrix=matrix)
28
+ mode = "RGBA" if pix.alpha else "RGB"
29
+ pil_image = Image.frombytes(mode, [pix.width, pix.height], pix.samples)
30
+ images_list.append(pil_image)
31
  return images_list
32
 
33
  def create_zip_from_images(images_list):
34
  """
35
+ Create a ZIP file in memory from a list of PIL.Image objects.
36
+
37
+ Args:
38
+ images_list (list): A list of PIL.Image objects
39
+
40
+ Returns:
41
+ BytesIO: A BytesIO object representing the ZIP file
42
  """
43
+ zip_buffer = io.BytesIO()
44
+ with zipfile.ZipFile(zip_buffer, 'w', zipfile.ZIP_DEFLATED) as zf:
45
+ for idx, img in enumerate(images_list):
46
+ img_bytes = io.BytesIO()
47
+ img.save(img_bytes, format="PNG")
48
+ img_bytes.seek(0)
49
+ zf.writestr(f"page_{idx+1}.png", img_bytes.read())
50
+ zip_buffer.seek(0)
51
+ return zip_buffer
52
 
53
+ def main():
 
 
54
  """
55
+ Streamlit application entry point.
56
+ Provides a PDF-to-image converter that outputs a ZIP file without using Poppler.
57
  """
58
+ st.title("PDFを画像に変換 (PyMuPDF 版)")
59
+ st.write("""
60
+ Poppler を使わずに PyMuPDF を用いて PDF を各ページごとに PNG へ変換し、
61
+ ZIP にまとめてダウンロードできるサンプルアプリです。
62
+ """)
 
 
63
 
64
+ uploaded_file = st.file_uploader("PDFファイルをアップロードしてください", type=["pdf"])
 
 
 
 
 
 
 
 
65
 
66
+ if uploaded_file is not None:
67
+ dpi = st.slider("解像度(dpi)を選択してください", min_value=72, max_value=600, value=144, step=72)
 
 
 
 
 
 
 
 
 
 
68
 
69
+ if st.button("変換開始"):
70
+ try:
71
+ with st.spinner("変換中...しばらくお待ちください"):
72
+ images_converted = convert_pdf_to_images(uploaded_file.read(), dpi)
73
+ zip_file_bytes = create_zip_from_images(images_converted)
74
+
75
  st.success("変換が完了しました!")
76
  st.download_button(
77
  label="ZIPファイルをダウンロード",
 
80
  mime="application/zip"
81
  )
82
 
83
+ # Preview images (optional)
84
+ st.write("変換された画像のプレビュー:")
85
+ for idx, image_item in enumerate(images_converted):
86
+ st.image(image_item, caption=f"ページ {idx+1}", use_column_width=True)
87
+
88
+ except Exception as e:
89
+ st.error(f"変換中にエラーが発生しました: {str(e)}")
90
 
91
+ if __name__ == "__main__":
92
+ main()