Spaces:
Running
Running
import gradio as gr | |
import subprocess | |
import json | |
import os | |
import stat | |
import zipfile | |
from PIL import ImageFont | |
import matplotlib.font_manager | |
# Path to the compiled engine executable | |
ENGINE_EXECUTABLE = "./engine" | |
def ensure_executable(file_path): | |
""" | |
Đảm bảo rằng file có quyền thực thi. | |
Nếu không, cấp quyền thực thi. | |
""" | |
if not os.access(file_path, os.X_OK): # Kiểm tra quyền thực thi | |
try: | |
# Cấp quyền thực thi | |
current_permissions = os.stat(file_path).st_mode | |
os.chmod(file_path, current_permissions | stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH) | |
print(f"Granted execute permission to {file_path}") | |
except Exception as e: | |
raise PermissionError(f"Failed to grant execute permission to {file_path}: {e}") | |
def extract_and_load_fonts_from_directory(directory="fontfile", extract_to="extracted_fonts"): | |
if not os.path.exists(extract_to): | |
os.makedirs(extract_to) | |
fonts = [] | |
# Extract fonts from zip files | |
for root, dirs, files in os.walk(directory): | |
for file in files: | |
if file.endswith(".zip"): | |
zip_path = os.path.join(root, file) | |
try: | |
with zipfile.ZipFile(zip_path, 'r') as zip_ref: | |
zip_ref.extractall(extract_to) | |
print(f"Extracted: {zip_path}") | |
except Exception as e: | |
print(f"Failed to extract {zip_path}: {e}") | |
# Collect all .ttf and .shx fonts | |
for root, dirs, files in os.walk(extract_to): | |
for file in files: | |
if file.endswith(".ttf") or file.endswith(".shx"): | |
fonts.append(os.path.join(root, file)) | |
return fonts | |
def get_system_fonts(): | |
fonts = [] | |
for font in matplotlib.font_manager.findSystemFonts(fontpaths=None, fontext='ttf'): | |
fonts.append(font) | |
return fonts | |
def get_available_fonts(): | |
# Get system fonts | |
system_fonts = get_system_fonts() | |
# Extract and load custom fonts | |
extracted_fonts = extract_and_load_fonts_from_directory() | |
# Combine and deduplicate fonts | |
all_fonts = list(set(system_fonts + extracted_fonts)) | |
return sorted(all_fonts) | |
def call_engine(input_text, font_size, width, height, bg_color, text_color, mode, font_name, align, line_spacing, image_format): | |
# Ensure the engine file is executable | |
ensure_executable(ENGINE_EXECUTABLE) | |
# Prepare input data as a dictionary | |
input_data = { | |
"input_text": input_text, | |
"font_size": font_size, | |
"width": width, | |
"height": height, | |
"bg_color": bg_color, | |
"text_color": text_color, | |
"mode": mode, | |
"font_path": font_name, # Pass the selected font path | |
"align": align, | |
"line_spacing": line_spacing, | |
"image_format": image_format | |
} | |
# Call the engine executable with input data | |
result = subprocess.run( | |
[ENGINE_EXECUTABLE, json.dumps(input_data)], | |
capture_output=True, | |
text=True | |
) | |
# Handle errors | |
if result.returncode != 0: | |
raise Exception(f"Engine failed with error: {result.stderr}") | |
# Get the output image path from stdout | |
output_path = result.stdout.strip() | |
# Load the generated image | |
if os.path.exists(output_path): | |
return output_path | |
else: | |
raise Exception("Failed to generate image!") | |
with gr.Blocks() as demo: | |
gr.Markdown("# 🖼️ Text to Image Converter") | |
with gr.Row(): | |
input_text = gr.Textbox(label="Enter Text", placeholder="Type or paste text here...", lines=5) | |
file_input = gr.File(label="Upload a Text File", type="filepath") | |
with gr.Row(): | |
font_size = gr.Slider(10, 100, value=30, label="Font Size") | |
# Lấy danh sách font và đặt font mặc định là font đầu tiên | |
available_fonts = get_available_fonts() | |
default_font = available_fonts[0] if available_fonts else "" | |
font_name = gr.Dropdown(choices=available_fonts, value=default_font, label="Font") | |
align = gr.Radio(["Left", "Center", "Right"], label="Text Alignment", value="Center") | |
with gr.Row(): | |
width = gr.Slider(200, 2000, value=800, label="Image Width") | |
height = gr.Slider(200, 2000, value=600, label="Base Height") | |
with gr.Row(): | |
bg_color = gr.ColorPicker(label="Background Color", value="#FFFFFF") | |
text_color = gr.ColorPicker(label="Text Color", value="#000000") | |
with gr.Row(): | |
mode = gr.Radio(["Plain Text", "LaTeX Math"], label="Rendering Mode", value="Plain Text") | |
image_format = gr.Radio(["PNG", "JPEG"], label="Image Format", value="PNG") | |
# Add line spacing slider | |
line_spacing = gr.Slider(1.0, 3.0, value=1.2, step=0.1, label="Line Spacing") | |
output_image = gr.Image(label="Generated Image") | |
with gr.Row(): | |
convert_button = gr.Button("Convert Text to Image") | |
file_convert_button = gr.Button("Convert File to Image") | |
convert_button.click( | |
call_engine, | |
inputs=[ | |
input_text, font_size, width, height, bg_color, text_color, | |
mode, font_name, align, line_spacing, image_format | |
], | |
outputs=output_image | |
) | |
demo.launch() | |