From de49510ff363d27ca8fb648a040475059fa8f484 Mon Sep 17 00:00:00 2001 From: Ricco Lim Date: Tue, 3 Sep 2024 23:38:57 +0800 Subject: [PATCH] Add README and ScoreFlip.py --- README.md | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ ScoreFlip.py | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 README.md create mode 100644 ScoreFlip.py diff --git a/README.md b/README.md new file mode 100644 index 0000000..9f6d8d8 --- /dev/null +++ b/README.md @@ -0,0 +1,71 @@ +# ScoreFlip + +**ScoreFlip** is a simple yet powerful tool designed for musicians who use digital music scores. If you've ever struggled with flipping pages smoothly during performances using existing Music Score Reader apps on Windows, ScoreFlip is here to help. + +## Features + +- **Seamless Page Transition**: Automatically insert combined pages between existing ones to ensure smooth transitions during page flips. +- **High-Quality Output**: Maintains the quality of your music scores, ensuring that every note is clear and easy to read. +- **Easy-to-Use Interface**: Simple import and export functionality with minimal setup. +- **Optimized for Performances**: Designed specifically with the needs of live performers in mind, ScoreFlip ensures you never miss a beat while flipping pages. + +## Why ScoreFlip? + +As a musician, you know the frustration of flipping through digital music scores during a live performance. Many existing Windows apps only flip full pages. ScoreFlip was created out of this need for a better solution. + +## Installation + +1. **Download the latest version** of ScoreFlip from the [releases page](#). +2. **Run the installer** and follow the on-screen instructions to complete the installation. + +## Usage + +1. **Open ScoreFlip**. +2. Click the **Import PDF** button to select your digital music score. +3. Once imported, click **Download PDF** to save the modified score with seamless page transitions. +4. Use the modified PDF in your favorite Music Score Reader app for uninterrupted performances. + +## Requirements + +- Windows 10 or later +- Python 3.7+ +- PyMuPDF (Installed automatically with the app) + +## Development + +If you'd like to contribute to ScoreFlip or modify it for your own use, you can clone this repository and run the app locally. + +### Running Locally + +1. Clone this repository: + ```bash + git clone https://github.com/riccoljy/ScoreFlip.git + ``` +2. Navigate to the project directory: + ```bash + cd ScoreFlip + ``` +3. Install the required dependencies: + ```bash + pip install -r requirements.txt + ``` +4. Run the app: + ```bash + python app.py + ``` + +## License + +ScoreFlip is licensed under the MIT License. See the [LICENSE](LICENSE) file for more details. + +## Acknowledgements + +ScoreFlip was born out of the frustration of struggling with existing digital music score readers. Special thanks to the community of musicians who provided invaluable feedback during development. + +## Contact + +For support, questions, or suggestions, feel free to reach out at [riccoljy@gmail.com](mailto:riccoljy@gmail.com). + +--- + +Happy playing with ScoreFlip! 🎵 diff --git a/ScoreFlip.py b/ScoreFlip.py new file mode 100644 index 0000000..c89d3f5 --- /dev/null +++ b/ScoreFlip.py @@ -0,0 +1,70 @@ +import fitz # PyMuPDF +import tkinter as tk +from tkinter import filedialog, messagebox + +def extract_half_page(pdf, page_num, half='top'): + page = pdf.load_page(page_num) + width, height = page.rect.width, page.rect.height + if half == 'top': + clip_rect = fitz.Rect(0, 0, width, height / 2) + else: + clip_rect = fitz.Rect(0, height / 2, width, height) + + new_pdf = fitz.open() + new_page = new_pdf.new_page(width=width, height=height / 2) + new_page.show_pdf_page(fitz.Rect(0, 0, width, height / 2), pdf, page_num, clip=clip_rect) + + return new_pdf + +def create_combined_page(top_half_pdf, bottom_half_pdf, width, height): + combined_pdf = fitz.open() + new_page = combined_pdf.new_page(width=width, height=height) + new_page.show_pdf_page(fitz.Rect(0, 0, width, height / 2), top_half_pdf, 0) + new_page.show_pdf_page(fitz.Rect(0, height / 2, width, height), bottom_half_pdf, 0) + return combined_pdf + +def insert_combined_pages(input_pdf_path, output_pdf_path): + pdf = fitz.open(input_pdf_path) + output_pdf = fitz.open() + for i in range(len(pdf) - 1): + output_pdf.insert_pdf(pdf, from_page=i, to_page=i) + bottom_half_pdf = extract_half_page(pdf, i, half='bottom') + top_half_pdf = extract_half_page(pdf, i + 1, half='top') + width, height = pdf[i].rect.width, pdf[i].rect.height + combined_page_pdf = create_combined_page(top_half_pdf, bottom_half_pdf, width, height) + output_pdf.insert_pdf(combined_page_pdf) + output_pdf.insert_pdf(pdf, from_page=len(pdf) - 1, to_page=len(pdf) - 1) + output_pdf.save(output_pdf_path) + +def import_pdf(): + input_file = filedialog.askopenfilename(filetypes=[("PDF Files", "*.pdf")]) + if input_file: + input_entry.delete(0, tk.END) + input_entry.insert(0, input_file) + +def export_pdf(): + if not input_entry.get(): + messagebox.showerror("Error", "Please import a PDF file first.") + return + output_file = filedialog.asksaveasfilename(defaultextension=".pdf", filetypes=[("PDF Files", "*.pdf")]) + if output_file: + insert_combined_pages(input_entry.get(), output_file) + messagebox.showinfo("Success", "PDF has been processed and saved successfully!") + +# Setup tkinter GUI +root = tk.Tk() +root.title("ScoreFlip") + +input_label = tk.Label(root, text="Import PDF:") +input_label.pack(pady=5) + +input_entry = tk.Entry(root, width=50) +input_entry.pack(pady=5) + +import_button = tk.Button(root, text="Import PDF", command=import_pdf) +import_button.pack(pady=5) + +export_button = tk.Button(root, text="Download PDF", command=export_pdf) +export_button.pack(pady=5) + +root.mainloop()