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()