基于Python实现Latex公式编辑器(输出png)

Key Features:
​​LaTeX Formula Input​​:
Directly input LaTeX math expressions like \int_0^4 dx
Supports complex formulas with fractions, integrals, matrices, etc.
​​Customization Options​​:
Color picker for formula text
Adjustable font size (8-72pt)
Resolution control (72-1200 DPI)
​​Preview Pane​​:
Real-time rendering of formulas
Interactive matplotlib canvas
Transparent background preview
​​Export Functions​​:
​​Export PNG​​: Save transparent PNG with high resolution
​​Copy to Clipboard​​: One-click paste into presentation software
Transparent background preserved in exports
​​High-Quality Output​​:
Vector-quality rendering at any resolution
Crisp text with anti-aliasing
Optimized padding around formulas
Requirements:
Python 3.6+
Required packages: matplotlib, numpy, pillow, tkinter
LaTeX distribution (MiKTeX or TeX Live) for full symbol support
Usage:
Enter LaTeX formula in the input field
Customize appearance using the options panel
Preview the result in real-time
Export as PNG or copy directly to clipboard
Paste into PowerPoint/Keynote with transparent background

在这里插入图片描述

import tkinter as tk
from tkinter import ttk, colorchooser, filedialog, messagebox
import matplotlib.pyplot as plt
import numpy as np
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from matplotlib.figure import Figure
import matplotlib as mpl
import io
import sys
from PIL import Image
import pyperclip
import tempfile
import os

class LaTeXRendererApp:
    def __init__(self, root):
        self.root = root
        self.root.title("LaTeX Formula Renderer")
        self.root.geometry("800x600")
        
        # Default settings
        self.formula = r"\int_0^4 dx"
        self.text_color = "#000000"
        self.bg_color = "transparent"
        self.font_size = 16
        self.dpi = 300
        
        # Create UI
        self.create_widgets()
        
    def create_widgets(self):
        # Main frame
        main_frame = ttk.Frame(self.root)
        main_frame.pack(fill=tk.BOTH, expand=True, padx=10, pady=10)
        
        # Input section
        input_frame = ttk.LabelFrame(main_frame, text="Formula Input")
        input_frame.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Label(input_frame, text="LaTeX Formula:").grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)
        self.formula_entry = ttk.Entry(input_frame, width=50)
        self.formula_entry.insert(0, self.formula)
        self.formula_entry.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W+tk.E)
        
        # Options section
        options_frame = ttk.LabelFrame(main_frame, text="Rendering Options")
        options_frame.pack(fill=tk.X, padx=5, pady=5)
        
        ttk.Label(options_frame, text="Text Color:").grid(row=0, column=0, sticky=tk.W, padx=5, pady=5)
        self.color_btn = ttk.Button(options_frame, text="Choose", command=self.choose_color)
        self.color_btn.grid(row=0, column=1, padx=5, pady=5, sticky=tk.W)
        
        ttk.Label(options_frame, text="Font Size:").grid(row=1, column=0, sticky=tk.W, padx=5, pady=5)
        self.font_size_var = tk.StringVar(value=str(self.font_size))
        font_size_spin = tk.Spinbox(options_frame, from_=8, to=72, width=5, 
                                    textvariable=self.font_size_var)
        font_size_spin.grid(row=1, column=1, padx=5, pady=5, sticky=tk.W)
        
        ttk.Label(options_frame, text="DPI (Resolution):").grid(row=2, column=0, sticky=tk.W, padx=5, pady=5)
        self.dpi_var = tk.StringVar(value=str(self.dpi))
        dpi_spin = tk.Spinbox(options_frame, from_=72, to=1200, width=5, textvariable=self.dpi_var)
        dpi_spin.grid(row=2, column=1, padx=5, pady=5, sticky=tk.W)
        
        # Preview section
        preview_frame = ttk.LabelFrame(main_frame, text="Preview")
        preview_frame.pack(fill=tk.BOTH, expand=True, padx=5, pady=5)
        
        # Matplotlib figure setup
        self.fig = Figure(facecolor="none", edgecolor="none")
        self.ax = self.fig.add_axes([0, 0, 1, 1])  # Full figure
        self.ax.axis("off")
        
        # Tkinter canvas for embedding matplotlib figure
        self.canvas = FigureCanvasTkAgg(self.fig, master=preview_frame)
        self.canvas.draw()
        self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)
        
        # Action buttons
        btn_frame = ttk.Frame(main_frame)
        btn_frame.pack(fill=tk.X, padx=5, pady=5)
        
        render_btn = ttk.Button(btn_frame, text="Render Preview", command=self.render_preview)
        render_btn.pack(side=tk.LEFT, padx=5, pady=5)
        
        export_btn = ttk.Button(btn_frame, text="Export PNG", command=self.export_png)
        export_btn.pack(side=tk.LEFT, padx=5, pady=5)
        
        copy_btn = ttk.Button(btn_frame, text="Copy to Clipboard", command=self.copy_to_clipboard)
        copy_btn.pack(side=tk.LEFT, padx=5, pady=5)
        
        # Set default formula
        self.render_preview()
    
    def choose_color(self):
        color = colorchooser.askcolor(title="Select Text Color")
        if color[1]:
            self.text_color = color[1]
    
    def render_preview(self):
        # Get current values
        self.formula = self.formula_entry.get()
        try:
            self.font_size = int(self.font_size_var.get())
        except ValueError:
            pass
        
        # Clear previous content
        self.ax.clear()
        self.ax.axis("off")
        
        # Render LaTeX formula at center
        self.ax.text(0.5, 0.5, f"${self.formula}$", 
                    fontsize=self.font_size, 
                    color=self.text_color,
                    verticalalignment="center",
                    horizontalalignment="center")
        
        # Remove padding around equation
        self.fig.tight_layout(pad=0)
        
        # Update canvas
        self.canvas.draw()
    
    def export_png(self):
        try:
            self.dpi = int(self.dpi_var.get())
        except ValueError:
            pass
        
        file_path = filedialog.asksaveasfilename(
            defaultextension=".png",
            filetypes=[("PNG files", "*.png"), ("All files", "*.*")],
            title="Save Formula as PNG"
        )
        
        if not file_path:
            return
        
        # Render to file with tight cropping and transparency
        self.fig.savefig(file_path, dpi=self.dpi, transparent=True, 
                         bbox_inches="tight", pad_inches=0)
        messagebox.showinfo("Export Successful", 
                           f"Equation saved as PNG with transparent background\n"
                           f"Resolution: {self.dpi} DPI\n"
                           f"Location: {file_path}")
    
    def copy_to_clipboard(self):
        try:
            self.dpi = int(self.dpi_var.get())
        except ValueError:
            pass
        
        # Render to in-memory buffer
        buf = io.BytesIO()
        self.fig.savefig(buf, format="png", dpi=self.dpi, transparent=True,
                         bbox_inches="tight", pad_inches=0)
        buf.seek(0)
        
        # Save to temporary file
        with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as temp_file:
            temp_file.write(buf.read())
            temp_path = temp_file.name
        
        # Copy image to clipboard using pyperclip [8,9,10](@ref)
        try:
            # For Windows: save to clipboard as file reference
            if sys.platform.startswith('win'):
                cmd = f'powershell -command "Set-Clipboard -Path \'{temp_path}\'"'
                os.system(cmd)
            # For macOS: use pbcopy
            elif sys.platform == 'darwin':
                os.system(f'osascript -e \'set the clipboard to (read (POSIX file "{temp_path}") as PNG picture)\'')
            # For Linux: use xclip
            else:
                os.system(f'xclip -selection clipboard -t image/png -i "{temp_path}"')
            
            messagebox.showinfo("Copied to Clipboard", 
                               "Equation copied to clipboard as transparent PNG\n"
                               "You can now paste it directly into PowerPoint")
        except Exception as e:
            messagebox.showerror("Clipboard Error", 
                                f"Could not copy to clipboard: {str(e)}\n"
                                "Equation saved to temporary file: {temp_path}")
        finally:
            # Clean up temporary file after a short delay
            self.root.after(5000, lambda: os.unlink(temp_path))
        
        buf.close()

if __name__ == "__main__":
    # Configure matplotlib for LaTeX rendering
    mpl.rcParams["text.usetex"] = True
    mpl.rcParams["font.family"] = "heiti"
    
    root = tk.Tk()
    app = LaTeXRendererApp(root)
    root.mainloop()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值