Spaces:
Sleeping
Sleeping
import gradio as gr | |
import numpy as np | |
from PIL import Image | |
import io | |
import base64 | |
# Import our custom modules | |
from utils.image_preprocessing import preprocess_image | |
from models.document_ai import extract_text_and_layout | |
from models.text_processor import process_menu_text | |
from models.braille_translator import text_to_braille, get_braille_metadata | |
from utils.pdf_generator import create_braille_pdf, create_braille_pdf_with_comparison | |
def generate_pdf(original_text, braille_text, title, comparison=False): | |
"""Generate a PDF file with Braille content.""" | |
try: | |
if comparison: | |
pdf_buffer = create_braille_pdf_with_comparison(original_text, braille_text, title) | |
else: | |
pdf_buffer = create_braille_pdf(original_text, braille_text, title) | |
return pdf_buffer | |
except Exception as e: | |
print(f"Error in generate_pdf: {str(e)}") | |
raise | |
# Function to create a download link for a PDF | |
def generate_pdf1(original_text, braille_text, title, comparison=False): | |
"""Generate a PDF file with Braille content.""" | |
if comparison: | |
pdf_buffer = create_braille_pdf_with_comparison(original_text, braille_text, title) | |
else: | |
pdf_buffer = create_braille_pdf(original_text, braille_text, title) | |
return pdf_buffer | |
def process_image_v2(image, use_llm, use_context): | |
"""Process the uploaded image and generate results.""" | |
if image is None: | |
return "Please upload an image first.", "", "", None | |
# Convert to PIL Image if needed | |
if isinstance(image, np.ndarray): | |
image = Image.fromarray(image) | |
# Preprocess the image | |
preprocessed_img = preprocess_image(image) | |
# Extract text using document AI | |
try: | |
result = extract_text_and_layout(preprocessed_img) | |
if not result.get('words', []): | |
return "No text was extracted from the image.", "", "", None | |
raw_text = ' '.join(result['words']) | |
# Process text with LLM if enabled | |
if use_llm: | |
processed_result = process_menu_text(raw_text) | |
if processed_result['success']: | |
processed_text = processed_result['structured_text'] | |
else: | |
processed_text = raw_text | |
else: | |
processed_text = raw_text | |
# Translate to Braille | |
braille_result = text_to_braille(processed_text, use_context=use_context) | |
if not braille_result['success']: | |
return processed_text, "", "Braille translation failed.", None | |
braille_text = braille_result['formatted_braille'] | |
# Generate metadata | |
metadata = get_braille_metadata(processed_text) | |
metadata_text = f"Translation contains {metadata['word_count']} words, {metadata['character_count']} characters, {metadata['line_count']} lines." | |
# Store both Unicode and ASCII versions for later use | |
state_data = { | |
'original_text': processed_text, | |
'braille_text': braille_text, | |
'ascii_braille': braille_result.get('formatted_ascii', '') | |
} | |
# Return results | |
return processed_text, braille_text, metadata_text, state_data | |
except Exception as e: | |
return f"Error processing image: {str(e)}", "", "", None | |
def process_image(image, use_llm, use_context): | |
"""Process the uploaded image and generate results.""" | |
if image is None: | |
return "Please upload an image first.", "", "", None | |
# Convert to PIL Image if needed | |
if isinstance(image, np.ndarray): | |
image = Image.fromarray(image) | |
# Preprocess the image | |
preprocessed_img = preprocess_image(image) | |
# Extract text using document AI | |
try: | |
result = extract_text_and_layout(preprocessed_img) | |
if not result.get('words', []): | |
return "No text was extracted from the image.", "", "", None | |
raw_text = ' '.join(result['words']) | |
# Process text with LLM if enabled | |
if use_llm: | |
processed_result = process_menu_text(raw_text) | |
if processed_result['success']: | |
processed_text = processed_result['structured_text'] | |
else: | |
processed_text = raw_text | |
else: | |
processed_text = raw_text | |
# Translate to Braille | |
braille_result = text_to_braille(processed_text, use_context=use_context) | |
if not braille_result['success']: | |
return processed_text, "", "Braille translation failed.", None | |
braille_text = braille_result['formatted_braille'] | |
# Generate metadata | |
metadata = get_braille_metadata(processed_text) | |
metadata_text = f"Translation contains {metadata['word_count']} words, {metadata['character_count']} characters, {metadata['line_count']} lines." | |
# Return results | |
return processed_text, braille_text, metadata_text, (processed_text, braille_text) | |
except Exception as e: | |
return f"Error processing image: {str(e)}", "", "", None | |
def create_pdf_v2(state, pdf_title, pdf_type): | |
"""Create a PDF file for download.""" | |
if state is None: | |
return None | |
# Extract data from state | |
try: | |
original_text = state['original_text'] | |
ascii_braille = state['ascii_braille'] | |
# If ASCII version is not available, use the Unicode version | |
if not ascii_braille: | |
ascii_braille = state['braille_text'] | |
except: | |
# Fallback for backward compatibility | |
if isinstance(state, tuple) and len(state) == 2: | |
original_text, braille_text = state | |
ascii_braille = braille_text | |
else: | |
return None | |
comparison = (pdf_type == "Side-by-Side Comparison") | |
try: | |
pdf_buffer = generate_pdf(original_text, ascii_braille, pdf_title, comparison) | |
# Create a temporary file to save the PDF | |
temp_file_path = f"/tmp/{pdf_title.replace(' ', '_').lower()}.pdf" | |
# Write the buffer to a file | |
with open(temp_file_path, "wb") as f: | |
f.write(pdf_buffer.getvalue()) | |
return temp_file_path | |
except Exception as e: | |
print(f"Error generating PDF: {str(e)}") | |
return None | |
def create_pdf(state, pdf_title, pdf_type): | |
"""Create a PDF file for download.""" | |
if state is None: | |
return None | |
# Extract data from state | |
try: | |
original_text = state['original_text'] | |
braille_text = state['braille_text'] # Use Unicode Braille text | |
except: | |
# Fallback for backward compatibility | |
if isinstance(state, tuple) and len(state) == 2: | |
original_text, braille_text = state | |
else: | |
return None | |
comparison = (pdf_type == "Side-by-Side Comparison") | |
try: | |
pdf_buffer = generate_pdf(original_text, braille_text, pdf_title, comparison) | |
# Create a temporary file to save the PDF | |
temp_file_path = f"/tmp/{pdf_title.replace(' ', '_').lower()}.pdf" | |
# Write the buffer to a file | |
with open(temp_file_path, "wb") as f: | |
f.write(pdf_buffer.getvalue()) | |
return temp_file_path | |
except Exception as e: | |
print(f"Error generating PDF: {str(e)}") | |
return None | |
def create_pdf_v1_working(state, pdf_title, pdf_type): | |
"""Create a PDF file for download.""" | |
if state is None or len(state) != 2: | |
return None | |
original_text, braille_text = state | |
# Get ASCII representation for PDF | |
try: | |
braille_result = text_to_braille(original_text, use_context=False) | |
ascii_braille = braille_result.get('formatted_ascii', braille_text) | |
except: | |
ascii_braille = braille_text | |
comparison = (pdf_type == "Side-by-Side Comparison") | |
try: | |
pdf_buffer = generate_pdf(original_text, ascii_braille, pdf_title, comparison) | |
# Create a temporary file to save the PDF | |
temp_file_path = f"/tmp/{pdf_title.replace(' ', '_').lower()}.pdf" | |
# Write the buffer to a file | |
with open(temp_file_path, "wb") as f: | |
f.write(pdf_buffer.getvalue()) | |
return temp_file_path | |
except Exception as e: | |
print(f"Error generating PDF: {str(e)}") | |
return None | |
def create_pdf2(state, pdf_title, pdf_type): | |
"""Create a PDF file for download.""" | |
if state is None or len(state) != 2: | |
return None | |
original_text, braille_text = state | |
comparison = (pdf_type == "Side-by-Side Comparison") | |
try: | |
pdf_buffer = generate_pdf(original_text, braille_text, pdf_title, comparison) | |
# Create a temporary file to save the PDF | |
temp_file_path = f"/tmp/{pdf_title.replace(' ', '_').lower()}.pdf" | |
# Write the buffer to a file | |
with open(temp_file_path, "wb") as f: | |
f.write(pdf_buffer.getvalue()) | |
return temp_file_path | |
except Exception as e: | |
print(f"Error generating PDF: {str(e)}") | |
return None | |
def create_pdf1(state, pdf_title, pdf_type): | |
"""Create a PDF file for download.""" | |
if state is None or len(state) != 2: | |
return None | |
original_text, braille_text = state | |
comparison = (pdf_type == "Side-by-Side Comparison") | |
pdf_buffer = generate_pdf(original_text, braille_text, pdf_title, comparison) | |
# Return the file for download | |
return pdf_buffer | |
# Create the Gradio interface | |
with gr.Blocks(title="English Menu to Braille Menu Converter") as demo: | |
gr.Markdown("# English Menu to Braille Menu") | |
gr.Markdown("Upload a menu image to convert it to Braille text") | |
with gr.Row(): | |
with gr.Column(scale=1): | |
# Input components | |
image_input = gr.Image(type="pil", label="Upload Menu Image") | |
with gr.Row(): | |
use_llm = gr.Checkbox(label="Use AI for text processing", value=True) | |
use_context = gr.Checkbox(label="Use AI for context enhancement", value=True) | |
process_button = gr.Button("Process Menu") | |
with gr.Column(scale=2): | |
# Output components | |
processed_text = gr.Textbox(label="Processed Text", lines=8) | |
braille_output = gr.Textbox(label="Braille Translation", lines=10) | |
metadata_output = gr.Markdown() | |
# Hidden state for PDF generation | |
state = gr.State() | |
# PDF download section | |
with gr.Group(): | |
gr.Markdown("### Download Options") | |
pdf_title = gr.Textbox(label="PDF Title", value="Menu in Braille") | |
pdf_type = gr.Radio( | |
["Sequential (Text then Braille)", "Side-by-Side Comparison"], | |
label="PDF Format", | |
value="Sequential (Text then Braille)" | |
) | |
pdf_button = gr.Button("Generate PDF") | |
pdf_output = gr.File(label="Download PDF") | |
# Set up event handlers | |
process_button.click( | |
process_image, | |
inputs=[image_input, use_llm, use_context], | |
outputs=[processed_text, braille_output, metadata_output, state] | |
) | |
pdf_button.click( | |
create_pdf, | |
inputs=[state, pdf_title, pdf_type], | |
outputs=[pdf_output] | |
) | |
# Add examples | |
gr.Examples( | |
examples=["assets/sample_menus/menu1.jpg", "assets/sample_menus/menu2.jpg"], | |
inputs=image_input | |
) | |
# Add about section | |
with gr.Accordion("About", open=False): | |
gr.Markdown(""" | |
This application converts menu images to Braille text using AI technologies: | |
- Document AI for text extraction | |
- LLMs for text processing and enhancement | |
- Braille translation with formatting | |
- PDF generation for download | |
Created as a demonstration of AI-powered accessibility tools. | |
""") | |
# Launch the app | |
if __name__ == "__main__": | |
demo.launch() | |