Spaces:
Sleeping
Sleeping
import os | |
import subprocess | |
import gradio as gr | |
from huggingface_hub import hf_hub_download | |
import logging | |
import tempfile | |
# Set up logging | |
logging.basicConfig( | |
level=logging.INFO, | |
format='%(asctime)s - %(levelname)s - %(message)s' | |
) | |
logger = logging.getLogger(__name__) | |
# Configuration | |
CLI_FILENAME = "Texttoimage" | |
REPO_ID = "ArrcttacsrjksX/Texttoimage" | |
FONT_LIST = ["Arial", "Times New Roman", "Courier New", "Comic Sans MS", "Verdana"] | |
DEFAULT_FONT = "Arial" | |
TEMP_DIR = tempfile.gettempdir() | |
def setup_cli_tool(): | |
"""Download and set up the CLI tool with proper error handling.""" | |
if os.path.exists(CLI_FILENAME): | |
logger.info(f"CLI tool already exists: {CLI_FILENAME}") | |
return True | |
hf_token = os.environ.get("HF_TOKEN") | |
if not hf_token: | |
logger.error("HF_TOKEN environment variable not set!") | |
return False | |
try: | |
logger.info(f"Downloading CLI tool from {REPO_ID}...") | |
cli_local_path = hf_hub_download( | |
repo_id=REPO_ID, | |
filename=CLI_FILENAME, | |
token=hf_token | |
) | |
if os.path.exists(cli_local_path): | |
if os.path.exists(CLI_FILENAME): | |
os.remove(CLI_FILENAME) | |
os.rename(cli_local_path, CLI_FILENAME) | |
os.chmod(CLI_FILENAME, 0o755) | |
logger.info(f"Successfully downloaded and set up CLI tool: {CLI_FILENAME}") | |
return True | |
else: | |
logger.error(f"Downloaded file not found at {cli_local_path}") | |
return False | |
except Exception as e: | |
logger.error(f"Error during CLI tool setup: {str(e)}") | |
return False | |
def read_text_file(file_path): | |
"""Read text from uploaded file.""" | |
try: | |
with open(file_path, 'r', encoding='utf-8') as f: | |
return f.read() | |
except Exception as e: | |
logger.error(f"Error reading file: {str(e)}") | |
return None | |
def text_to_image(text, font_size, width, height, bg_color, text_color, mode, font_name, align, image_format): | |
"""Convert text to image using the CLI tool.""" | |
if not text: | |
return "Error: No text provided", "Please enter text or upload a file" | |
if not os.path.exists(CLI_FILENAME): | |
if not setup_cli_tool(): | |
return None, "Error: Failed to set up Texttoimage. Please check logs and HF_TOKEN." | |
# Create unique output filename | |
output_path = os.path.join(TEMP_DIR, f"output_image_{os.getpid()}.{image_format.lower()}") | |
command = [ | |
f"./{CLI_FILENAME}", | |
"--text", text, | |
"--font-size", str(font_size), | |
"--width", str(width), | |
"--height", str(height), | |
"--bg-color", bg_color, | |
"--text-color", text_color, | |
"--mode", mode.lower(), | |
"--font", font_name, | |
"--align", align.lower(), | |
"--format", image_format.lower(), | |
"--output", output_path | |
] | |
try: | |
result = subprocess.run(command, check=True, capture_output=True, text=True) | |
if os.path.exists(output_path): | |
return output_path, "Image generated successfully!" | |
else: | |
logger.error(f"Output file not created: {output_path}") | |
logger.error(f"Command output: {result.stdout}") | |
logger.error(f"Command error: {result.stderr}") | |
return None, "Error: Failed to generate image. Check logs for details." | |
except subprocess.CalledProcessError as e: | |
logger.error(f"CLI tool execution failed: {str(e)}") | |
logger.error(f"Command output: {e.stdout}") | |
logger.error(f"Command error: {e.stderr}") | |
return None, f"Error: Failed to generate image: {str(e)}" | |
def handle_file_upload(file_path): | |
"""Handle file upload and return text content.""" | |
if file_path is None: | |
return None, "No file uploaded" | |
text = read_text_file(file_path) | |
if text is None: | |
return None, "Error reading file" | |
return text, "File uploaded successfully!" | |
# Create Gradio interface | |
with gr.Blocks(title="Text to Image Converter") as demo: | |
gr.Markdown("# 🖼️ Text to Image Converter") | |
# Status message | |
status_msg = gr.Markdown("Status: Ready") | |
# Input section | |
with gr.Row(): | |
with gr.Column(): | |
input_text = gr.Textbox( | |
label="Enter Text", | |
placeholder="Type or paste text here...", | |
lines=5 | |
) | |
file_input = gr.File( | |
label="Or Upload a Text File", | |
type="filepath" | |
) | |
# Settings section | |
with gr.Row(): | |
with gr.Column(): | |
font_size = gr.Slider( | |
minimum=10, | |
maximum=100, | |
value=30, | |
label="Font Size" | |
) | |
font_name = gr.Dropdown( | |
choices=FONT_LIST, | |
value=DEFAULT_FONT, | |
label="Font" | |
) | |
align = gr.Radio( | |
choices=["Left", "Center", "Right"], | |
label="Text Alignment", | |
value="Center" | |
) | |
with gr.Row(): | |
with gr.Column(): | |
width = gr.Slider( | |
minimum=200, | |
maximum=2000, | |
value=800, | |
label="Image Width" | |
) | |
height = gr.Slider( | |
minimum=200, | |
maximum=2000, | |
value=600, | |
label="Base Height" | |
) | |
with gr.Row(): | |
with gr.Column(): | |
bg_color = gr.ColorPicker( | |
label="Background Color", | |
value="#FFFFFF" | |
) | |
text_color = gr.ColorPicker( | |
label="Text Color", | |
value="#000000" | |
) | |
with gr.Row(): | |
with gr.Column(): | |
mode = gr.Radio( | |
choices=["Plain Text", "LaTeX Math"], | |
label="Rendering Mode", | |
value="Plain Text" | |
) | |
image_format = gr.Radio( | |
choices=["PNG", "JPEG"], | |
label="Image Format", | |
value="PNG" | |
) | |
# Output section | |
output_image = gr.Image(label="Generated Image") | |
# Buttons | |
with gr.Row(): | |
convert_button = gr.Button("Convert Text to Image", variant="primary") | |
clear_button = gr.Button("Clear", variant="secondary") | |
# Event handlers | |
def convert_with_status(*args): | |
status_msg.update("Converting...") | |
result, message = text_to_image(*args) | |
status_msg.update(message) | |
return result | |
def clear_inputs(): | |
return { | |
input_text: "", | |
output_image: None, | |
status_msg: gr.Markdown("Status: Ready") | |
} | |
def handle_file_upload_event(file_path): | |
text, message = handle_file_upload(file_path) | |
status_msg.update(message) | |
return text if text else "" | |
# Set up event listeners | |
convert_button.click( | |
fn=convert_with_status, | |
inputs=[ | |
input_text, font_size, width, height, | |
bg_color, text_color, mode, font_name, | |
align, image_format | |
], | |
outputs=output_image | |
) | |
clear_button.click( | |
fn=clear_inputs, | |
inputs=[], | |
outputs=[input_text, output_image, status_msg] | |
) | |
file_input.upload( | |
fn=handle_file_upload_event, | |
inputs=[file_input], | |
outputs=[input_text] | |
) | |
# Launch the application | |
if __name__ == "__main__": | |
try: | |
demo.launch( | |
server_name="0.0.0.0", | |
server_port=7860, | |
share=False, | |
show_error=True | |
) | |
except Exception as e: | |
logger.error(f"Failed to launch application: {str(e)}") |