Byaidu 1 год назад
Родитель
Сommit
53b58a55f6
8 измененных файлов с 96 добавлено и 82 удалено
  1. 7 3
      README.md
  2. 18 0
      docs/README_GUI.md
  3. 0 0
      docs/images/after.png
  4. 0 0
      docs/images/before.png
  5. 0 26
      gui/README.md
  6. 59 52
      pdf2zh/gui.py
  7. 11 1
      pdf2zh/pdf2zh.py
  8. 1 0
      setup.py

+ 7 - 3
README.md

@@ -135,11 +135,15 @@ Use regex to specify formula fonts and characters that need to be preserved.
 pdf2zh example.pdf -f "(CM[^RT].*|MS.*|.*Ital)" -c "(\(|\||\)|\+|=|\d|[\u0080-\ufaff])"
 pdf2zh example.pdf -f "(CM[^RT].*|MS.*|.*Ital)" -c "(\(|\||\)|\+|=|\d|[\u0080-\ufaff])"
 ```
 ```
 
 
-### Using GUI
+### Interact with GUI
 
 
-![image](./gui/img/before.png)
+![image](./docs/images/before.png)
 
 
-See [documentation for GUI](./gui/README.md) for more details.
+```bash
+pdf2zh -i
+```
+
+See [documentation for GUI](./docs/README_GUI.md) for more details.
 
 
 ## Preview
 ## Preview
 
 

+ 18 - 0
docs/README_GUI.md

@@ -0,0 +1,18 @@
+# Interact with GUI
+
+This subfolder provides the GUI mode of `pdf2zh`.
+
+## Usage
+
+1. Run `pdf2zh -i`
+
+2. Drop the PDF file into the window and click `Translate`.
+
+## Preview
+
+![image](./images/before.png)
+![image](./images/after.png)
+
+## Maintainance
+
+GUI maintained by [Rongxin](https://github.com/reycn)

+ 0 - 0
gui/img/after.png → docs/images/after.png


+ 0 - 0
gui/img/before.png → docs/images/before.png


+ 0 - 26
gui/README.md

@@ -1,26 +0,0 @@
-# GUI (early test version)
-
-This subfolder provides the GUI mode of `pdf2zh`.
-
-## Usage:
-1. Make sure that the main tool and additional dependencies are installed. Extra modules required by the GUI are:
-
-- GUI framework: `pip install gradio`
-- PDF preview: `pip install pdf2image`
-- PDF converter:
-- - Mac `brew install poppler`
-- - Other platforms: see [the link](https://pypi.org/project/pdf2image/) for details
-
-2. Run
-- `cd gui`
-- `python main.py`
-
-3. Drop the PDF file into the window and click `Translate`.
-
-## Sample PDFs:
-
-  <img src="./img/before.png" width="650" alt="Original">
-  <img src="./img/after.png" width="650" alt="Translated">
-
-## Maintainance
-GUI maintained by [Rongxin](https://github.com/reycn)

+ 59 - 52
gui/main.py → pdf2zh/gui.py

@@ -5,8 +5,15 @@ import tempfile
 from pathlib import Path
 from pathlib import Path
 
 
 import gradio as gr
 import gradio as gr
-from pdf2image import convert_from_path
+import pymupdf
+import numpy as np
 
 
+def pdf_preview(file):
+    doc=pymupdf.open(file)
+    page=doc[0]
+    pix=page.get_pixmap()
+    image=np.frombuffer(pix.samples, np.uint8).reshape(pix.height, pix.width, 3)
+    return image
 
 
 def upload_file(file, service, progress=gr.Progress()):
 def upload_file(file, service, progress=gr.Progress()):
     """Handle file upload, validation, and initial preview."""
     """Handle file upload, validation, and initial preview."""
@@ -16,8 +23,7 @@ def upload_file(file, service, progress=gr.Progress()):
     progress(0.3, desc="Converting PDF for preview...")
     progress(0.3, desc="Converting PDF for preview...")
     try:
     try:
         # Convert first page for preview
         # Convert first page for preview
-        images = convert_from_path(file, first_page=1, last_page=1)
-        preview_image = images[0] if images else None
+        preview_image=pdf_preview(file)
 
 
         return file, preview_image, gr.update(visible=True)
         return file, preview_image, gr.update(visible=True)
     except Exception as e:
     except Exception as e:
@@ -62,7 +68,7 @@ def translate(file_path, service, progress=gr.Progress()):
         final_output = output_dir / f"translated_{os.path.basename(file_path)}"
         final_output = output_dir / f"translated_{os.path.basename(file_path)}"
 
 
         # Execute translation command
         # Execute translation command
-        command = f"cd '{temp_path}' && pdf2zh '{input_pdf}' -s {selected_service}"
+        command = f'cd "{temp_path}" && pdf2zh "{input_pdf}" -s {selected_service}'
         print(f"Executing command: {command}")
         print(f"Executing command: {command}")
         print(f"Files in temp directory: {os.listdir(temp_path)}")
         print(f"Files in temp directory: {os.listdir(temp_path)}")
 
 
@@ -109,9 +115,7 @@ def translate(file_path, service, progress=gr.Progress()):
         # Generate preview of translated PDF
         # Generate preview of translated PDF
         progress(0.9, desc="Generating preview...")
         progress(0.9, desc="Generating preview...")
         try:
         try:
-            translated_preview = convert_from_path(
-                str(final_output), first_page=1, last_page=1
-            )[0]
+            translated_preview=pdf_preview(str(final_output))
         except Exception as e:
         except Exception as e:
             print(f"Error generating preview: {e}")
             print(f"Error generating preview: {e}")
             translated_preview = None
             translated_preview = None
@@ -119,49 +123,52 @@ def translate(file_path, service, progress=gr.Progress()):
     progress(1.0, desc="Translation complete!")
     progress(1.0, desc="Translation complete!")
     return str(final_output), translated_preview, gr.update(visible=True)
     return str(final_output), translated_preview, gr.update(visible=True)
 
 
+def setup_gui():
+    with gr.Blocks(title="PDF Translation") as app:
+        gr.Markdown("# PDF Translation")
+
+        with gr.Row():
+            with gr.Column(scale=1):
+                service = gr.Dropdown(
+                    label="Service",
+                    choices=["Google", "DeepL", "DeepLX", "Ollama"],
+                    value="Google",
+                )
+
+                file_input = gr.File(
+                    label="Upload",
+                    file_count="single",
+                    file_types=[".pdf"],
+                    type="filepath",
+                )
+
+                output_file = gr.File(label="Download Translation", visible=False)
+                translate_btn = gr.Button("Translate", variant="primary", visible=False)
+                # add a text description
+                gr.Markdown(
+                    """*Note: Please make sure that [pdf2zh](https://github.com/Byaidu/PDFMathTranslate) is correctly configured.*
+                    GUI implemented by: [Rongxin](https://github.com/reycn)
+                    [Early Version]
+                    """
+                )
+
+            with gr.Column(scale=2):
+                preview = gr.Image(label="Preview", visible=True)
+
+        # Event handlers
+        file_input.upload(
+            upload_file,
+            inputs=[file_input, service],
+            outputs=[file_input, preview, translate_btn],
+        )
+
+        translate_btn.click(
+            translate,
+            inputs=[file_input, service],
+            outputs=[output_file, preview, output_file],
+        )
+
+    app.launch(debug=True, inbrowser=True, share=False)
 
 
-with gr.Blocks(title="PDF Translation") as app:
-    gr.Markdown("# PDF Translation")
-
-    with gr.Row():
-        with gr.Column(scale=1):
-            service = gr.Dropdown(
-                label="Service",
-                choices=["Google", "DeepL", "DeepLX", "Ollama"],
-                value="Google",
-            )
-
-            file_input = gr.File(
-                label="Upload",
-                file_count="single",
-                file_types=[".pdf"],
-                type="filepath",
-            )
-
-            output_file = gr.File(label="Download Translation", visible=False)
-            translate_btn = gr.Button("Translate", variant="primary", visible=False)
-            # add a text description
-            gr.Markdown(
-                """*Note: Please make sure that [pdf2zh](https://github.com/Byaidu/PDFMathTranslate) is correctly configured.*
-                GUI implemented by: [Rongxin](https://github.com/reycn)
-                [Early Version]
-                """
-            )
-
-        with gr.Column(scale=2):
-            preview = gr.Image(label="Preview", visible=True)
-
-    # Event handlers
-    file_input.upload(
-        upload_file,
-        inputs=[file_input, service],
-        outputs=[file_input, preview, translate_btn],
-    )
-
-    translate_btn.click(
-        translate,
-        inputs=[file_input, service],
-        outputs=[output_file, preview, output_file],
-    )
-
-app.launch(debug=True, inbrowser=True, share=False)
+if __name__ == '__main__':
+    setup_gui()

+ 11 - 1
pdf2zh/pdf2zh.py

@@ -15,6 +15,7 @@ import urllib.request
 
 
 from pdf2zh import __version__
 from pdf2zh import __version__
 from pdf2zh.pdfexceptions import PDFValueError
 from pdf2zh.pdfexceptions import PDFValueError
+from pdf2zh.gui import setup_gui
 from typing import Any, Container, Iterable, List, Optional, TYPE_CHECKING
 from typing import Any, Container, Iterable, List, Optional, TYPE_CHECKING
 
 
 if TYPE_CHECKING:
 if TYPE_CHECKING:
@@ -143,7 +144,7 @@ def create_parser() -> argparse.ArgumentParser:
         "files",
         "files",
         type=str,
         type=str,
         default=None,
         default=None,
-        nargs="+",
+        nargs="*",
         help="One or more paths to PDF files.",
         help="One or more paths to PDF files.",
     )
     )
     parser.add_argument(
     parser.add_argument(
@@ -218,6 +219,12 @@ def create_parser() -> argparse.ArgumentParser:
         default=4,
         default=4,
         help="The number of threads to execute translation.",
         help="The number of threads to execute translation.",
     )
     )
+    parse_params.add_argument(
+        "--interactive",
+        "-i",
+        action="store_true",
+        help="Interact with GUI.",
+    )
 
 
     return parser
     return parser
 
 
@@ -247,6 +254,9 @@ def main(args: Optional[List[str]] = None) -> int:
         for file in missing_files:
         for file in missing_files:
             print(f"  {file}", file=sys.stderr)
             print(f"  {file}", file=sys.stderr)
         return -1
         return -1
+    if parsed_args.interactive:
+        setup_gui()
+        return 0
 
 
     setup_log()
     setup_log()
     extract_text(**vars(parsed_args))
     extract_text(**vars(parsed_args))

+ 1 - 0
setup.py

@@ -30,6 +30,7 @@ setup(
         "deepl<1.19.1",
         "deepl<1.19.1",
         "openai",
         "openai",
         "azure-ai-translation-text<=1.0.1",
         "azure-ai-translation-text<=1.0.1",
+        "gradio",
     ],
     ],
     classifiers=[
     classifiers=[
         "Programming Language :: Python :: 3",
         "Programming Language :: Python :: 3",