import gradio as gr from PIL import Image import pytesseract import spacy from reportlab.lib.pagesizes import letter from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, Image as RLImage from reportlab.lib.styles import getSampleStyleSheet import os from datetime import datetime # Load NLP model for analysis try: nlp = spacy.load("en_core_web_sm") except OSError: os.system("python -m spacy download en_core_web_sm") nlp = spacy.load("en_core_web_sm") def analyze_text(text): """Analyze the writing style and content""" doc = nlp(text) # Calculate word count and lengths words = [token for token in doc if not token.is_punct] word_count = len(words) word_lengths = sum(len(token) for token in words) analysis = { "word_count": word_count, "sentence_count": len(list(doc.sents)), "avg_word_length": word_lengths / max(1, word_count), "pos_tags": {tag: 0 for tag in ["NOUN", "VERB", "ADJ", "ADV"]}, "readability": "Moderate", "sentiment": "Neutral" } # Count POS tags for token in doc: if token.pos_ in analysis["pos_tags"]: analysis["pos_tags"][token.pos_] += 1 # Simple readability assessment if analysis["avg_word_length"] < 4: analysis["readability"] = "Easy" elif analysis["avg_word_length"] > 6: analysis["readability"] = "Difficult" return analysis def create_pdf(text, analysis, image_path=None): """Generate PDF report""" timestamp = datetime.now().strftime("%Y%m%d_%H%M%S") pdf_path = f"handwriting_report_{timestamp}.pdf" doc = SimpleDocTemplate(pdf_path, pagesize=letter) styles = getSampleStyleSheet() story = [] # Title story.append(Paragraph("Handwriting Analysis Report", styles["Title"])) story.append(Spacer(1, 12)) # Add original image if provided if image_path and os.path.exists(image_path): try: img = RLImage(image_path, width=400, height=300) story.append(img) story.append(Spacer(1, 12)) except: pass # Extracted Text section story.append(Paragraph("Extracted Text:", styles["Heading2"])) story.append(Spacer(1, 12)) story.append(Paragraph(text, styles["Normal"])) story.append(Spacer(1, 24)) # Analysis section story.append(Paragraph("Writing Analysis:", styles["Heading2"])) story.append(Spacer(1, 12)) analysis_text = f""" Word Count: {analysis['word_count']}
Sentence Count: {analysis['sentence_count']}
Average Word Length: {analysis['avg_word_length']:.2f} characters
Readability: {analysis['readability']}

Part-of-Speech Distribution:
- Nouns: {analysis['pos_tags']['NOUN']}
- Verbs: {analysis['pos_tags']['VERB']}
- Adjectives: {analysis['pos_tags']['ADJ']}
- Adverbs: {analysis['pos_tags']['ADV']}

Overall Sentiment: {analysis['sentiment']} """ story.append(Paragraph(analysis_text, styles["Normal"])) doc.build(story) return pdf_path def process_handwriting(image): """Main processing function""" try: # Convert image to text text = pytesseract.image_to_string(image) if not text.strip(): return "No text could be extracted from the image.", None # Analyze the text analysis = analyze_text(text) # Save image temporarily for PDF temp_image_path = "temp_input_image.jpg" image.save(temp_image_path) # Create PDF report pdf_path = create_pdf(text, analysis, temp_image_path) # Clean up if os.path.exists(temp_image_path): os.remove(temp_image_path) return text, pdf_path except Exception as e: return f"Error processing image: {str(e)}", None # Gradio interface with gr.Blocks() as demo: gr.Markdown("# Handwriting Analysis Tool") gr.Markdown("Upload a handwritten image to extract text and get a writing analysis report.") with gr.Row(): with gr.Column(): image_input = gr.Image(label="Upload Handwritten Image", type="pil") submit_btn = gr.Button("Analyze") with gr.Column(): text_output = gr.Textbox(label="Extracted Text", lines=10) pdf_output = gr.File(label="Download Analysis Report") submit_btn.click( fn=process_handwriting, inputs=image_input, outputs=[text_output, pdf_output] ) if __name__ == "__main__": demo.launch()