ai_qc/backend/visual_qc_apps/text_readability/app.py
nickviljoen 66f1d1480b Add dedicated text_product_overlap check for L'Oreal profile
Revert text_readability to original (overlap is a layout issue, not a
readability one — LLM kept scoring it Pass because text was readable).

New text_product_overlap check uses a step-by-step approach:
1. Define the product hero zone (including translucent/glass elements)
2. Identify all marketing text
3. Check spatial overlap between text and hero zone
4. Compare good vs bad layout patterns

L'Oreal Static profile now has 4 checks at 2.5 weight each (was 3
checks at 3.33). Total check count: 66.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-09 10:46:13 +02:00

104 lines
No EOL
6.5 KiB
Python
Executable file

import os
import sys
# Add parent directory to path to import shared modules
sys.path.append(os.path.dirname(os.path.dirname(os.path.dirname(os.path.abspath(__file__)))))
from visual_qc_apps.flask_app_template import FlaskAppTemplate
class TextReadabilityApp(FlaskAppTemplate):
"""
Text Readability Check
"""
def __init__(self):
# Define the hardcoded prompt
prompt = """You are performing a visual quality control check on a digital marketing asset. Your task is to evaluate whether ALL marketing text in the asset is clearly readable and whether any text may be missing or hidden.
CRITICAL: Evaluate only the MARKETING/ADVERTISING TEXT added to the creative (headlines, slogans, CTAs, promotional text, dates, legal lines). DO NOT evaluate text that is part of product packaging, labels, or bottles shown in the image — product packaging text is not in scope.
MEASUREMENT DATA:
If OCR LAYOUT MEASUREMENTS are provided at the end of this prompt, use the computed text positions, character heights, and spacing values to supplement your visual assessment. Character height in pixels indicates actual text size. Margin percentages show how close text is to edges. Spacing values between elements show whether text has adequate breathing room.
=== STEP 1: IDENTIFY ALL MARKETING TEXT ===
1. Identify every marketing text element in the asset:
a. Headlines and main messages
b. Slogans and taglines
c. Calls to action (CTAs)
d. Promotional or descriptive body copy
e. Dates, offers, and legal/disclaimer lines
f. EXCLUDE: Text printed on product packaging, bottles, labels, or boxes
=== STEP 2: EVALUATE TEXT READABILITY ===
2. For each marketing text element, assess:
a. Text size — Is it large enough to be comfortably read on digital screens?
b. Font choice — Is the font clear and easily readable (not overly decorative)?
c. Contrast — Does the text stand out clearly against its immediate background?
d. Spacing — Is there sufficient spacing between letters, words, and lines?
e. Placement — Is the text placed over a clean area or over a busy/complex background?
3. Check for overlapping and obstruction issues (CRITICAL):
a. Text overlapping with images, making it hard to read
b. Text overlapping with other text elements (e.g., two languages layered on top of each other)
c. Elements obscuring or partially covering marketing text
d. Text extending beyond visible boundaries or cropped by edges
e. Text placed over complex/busy backgrounds without proper contrast treatment (shadow, overlay, box, etc.)
=== STEP 3: DETECT HIDDEN OR INVISIBLE TEXT (CRITICAL) ===
4. Actively scan for text that may be INVISIBLE or HIDDEN due to colour matching:
a. Look carefully at DARK areas of the asset — is there dark-coloured text (black, dark grey, dark brown) that blends into a dark background?
b. Look carefully at LIGHT areas of the asset — is there light-coloured text (white, cream, pale) that blends into a light background?
c. Check if any text appears to be the SAME COLOUR as or very similar to the background behind it, making it partially or fully invisible
d. Look for faint outlines, subtle shadows, or barely-visible letterforms that indicate text is present but unreadable
e. Check edges and corners of the asset for text that may be cut off or lost against the background
5. Assess whether the marketing message feels COMPLETE:
a. Does the asset appear to be missing key text elements that would normally be expected (e.g., a headline exists but no supporting copy, or a product is shown with no descriptive text)?
b. Are there empty areas where text would logically be placed but nothing is visible?
c. If text appears to be missing or invisible, this is a CRITICAL FAIL — score 1-2/10
IMPORTANT EXCEPTION — PRODUCT-ONLY IMAGES:
If the asset is a PRODUCT-ONLY photograph (e.g., a product shot for a comparison table, product catalogue, or e-commerce listing) that intentionally contains NO marketing text at all — only the product and its packaging — then this check is NOT APPLICABLE. In this case:
- Score 7/10 (neutral)
- Set text_readability to "Not Applicable"
- Explain that the asset is a product-only image with no marketing text to evaluate
- This is DIFFERENT from an asset that has marketing text that is hidden or invisible (which should still score 1-2)
The key distinction: a product-only shot has NO SPACE or LAYOUT designed for marketing text. An asset with hidden/invisible text has areas where text is expected but cannot be seen.
=== SCORING GUIDANCE ===
- Score 9-10: All marketing text is clear, readable, well-spaced, good contrast
- Score 7-8: Minor issues (slightly small disclaimer text, minor spacing concern)
- Score 7: Product-only image with no marketing text present (neutral — not applicable)
- Score 5-6: Moderate issues (some text hard to read, poor placement over busy area)
- Score 3-4: Significant issues (major text elements hard to read, poor contrast, overlapping text)
- Score 1-2: Critical failure (text invisible/hidden due to colour matching, major text completely unreadable, text EXPECTED but missing)
=== PASS/FAIL CRITERIA ===
- "Pass" if ALL marketing text elements are clear, readable, properly spaced, and no hidden/invisible text detected
- "Fail" if ANY marketing text is difficult to read, overlapping, obscured, poorly contrasted, hidden/invisible, or missing
YOUR OUTPUT MUST BE a JSON code block:
{
"text_readability": "Pass" or "Fail" or "Not Applicable",
"readability_score": "High", "Medium", or "Low",
"text_elements_found": ["List each marketing text element you identified"],
"hidden_text_check": "Pass" or "Fail" or "Suspected — [describe what appears hidden]",
"issues_found": ["List specific problems found"],
"score": 1-10,
"recommendations": ["Recommendation 1", "Recommendation 2"]
}
CRITICAL:
1. Always provide detailed analysis of what text was found and evaluated
2. Focus ONLY on marketing text, NOT product packaging text
3. Actively LOOK FOR hidden/invisible text — do not just evaluate what is obviously visible
4. If text appears to be missing or invisible in an asset that HAS a marketing layout, this is a critical failure (score 1-2). But if the asset is a product-only shot with no marketing layout, score 7/10 neutral.
5. Never return just "Pass" or "Fail" without explanation"""
# Initialize the Flask app with the prompt
super().__init__(__name__, prompt)
# Run the app if executed directly
if __name__ == "__main__":
app = TextReadabilityApp()
app.run(debug=True)