File size: 7,936 Bytes
5727128
 
 
 
 
 
ec05444
 
 
 
5727128
ec05444
 
 
 
 
 
 
 
 
 
 
 
5727128
ec05444
 
 
 
5727128
 
ec05444
 
 
 
 
 
 
5727128
 
 
 
 
 
 
 
 
 
 
 
ec05444
 
 
 
 
 
5727128
ec05444
 
 
5727128
 
 
ec05444
 
 
5727128
ec05444
 
 
5727128
ec05444
 
 
 
 
 
 
5727128
ec05444
 
 
 
 
5727128
ec05444
5727128
ec05444
 
 
 
 
 
 
 
 
5727128
 
ec05444
 
 
 
5727128
 
 
 
 
 
 
 
ec05444
 
 
5727128
ec05444
 
5727128
ec05444
5727128
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ec05444
5727128
ec05444
5727128
 
 
 
 
 
 
ec05444
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5727128
 
 
 
 
ec05444
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5727128
ec05444
 
 
 
 
5727128
 
ec05444
 
 
 
 
5727128
ec05444
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
"""
Dispatch AI — Arabic Calligraphy
Generate Arabic calligraphy art with FLUX.1-schnell.
Text input, style selector (Thuluth/Naskh/Diwani/Kufi/Modern), color scheme.
"""

import os
import io
import gradio as gr
from huggingface_hub import InferenceClient
from PIL import Image, ImageDraw

# --- Configuration -----------------------------------------------------------
HF_TOKEN = os.environ.get("HF_TOKEN", None)
MODEL_ID = "black-forest-labs/FLUX.1-schnell"

client = InferenceClient(model=MODEL_ID, token=HF_TOKEN)

BG_COLOR = "#0A0F1A"
ACCENT = "#1FE0E6"

# Calligraphy styles
STYLES = {
    "Thuluth": "Thuluth script, elegant large sweeping curves, ornate flowing letters, classical Islamic style",
    "Naskh": "Naskh script, clean readable traditional book script, rounded letters, classic",
    "Diwani": "Diwani script, decorative curved ornamental Ottoman style, intricate overlapping letters",
    "Kufi": "Kufic script, geometric angular blocky letters, strict grid pattern, ancient architectural style",
    "Modern": "Modern Arabic calligraphy, contemporary stylized abstract elegant fusion of traditional and modern art",
    "Nasta'liq": "Nasta'liq script, elegant Persian-Arabic style with hanging baseline, refined sloping letters",
    "Ruq'ah": "Ruq'ah script, compact fast style with sharp angles, traditional handwriting style",
}

# Color schemes: name -> (foreground desc, background desc)
COLOR_SCHEMES = {
    "Gold on Black": ("gold metallic letters", "deep black textured background"),
    "White on Blue": ("pure white letters", "rich deep blue gradient background"),
    "Silver on Dark": ("silver metallic letters", "dark charcoal gradient background"),
    "Gold on Green": ("gold letters", "deep emerald green background with Islamic patterns"),
    "White on Maroon": ("pure white letters", "rich maroon red gradient background"),
    "Bronze on Cream": ("bronze letters", "warm cream parchment background"),
    "Neon on Dark": ("glowing neon cyan letters", "dark black background with subtle glow"),
}

# Composition / layout options
COMPOSITIONS = {
    "Centered": "centered composition, elegant ornamental frame",
    "Circular": "circular medallion composition, decorative border",
    "Panel": "horizontal panel composition, framed like a mosque tile",
    "Freestyle": "freestyle abstract composition, no frame, artistic flow",
}

# Example prompts in Arabic
EXAMPLES_AR = [
    "بسم الله الرحمن الرحيم",
    "السلام عليكم ورحمة الله وبركاته",
    "الحب للوطن من الايمان",
    "العلم نور",
    "صبر جميل",
    "توكل على الله",
    "Dispatch AI",
    "الإمارات",
    "العزة للوطن",
]


def build_prompt(arabic_text, style, color_scheme, composition):
    """Construct a detailed prompt for FLUX."""
    style_desc = STYLES.get(style, STYLES["Thuluth"])
    fg, bg = COLOR_SCHEMES.get(color_scheme, COLOR_SCHEMES["Gold on Black"])
    comp_desc = COMPOSITIONS.get(composition, COMPOSITIONS["Centered"])

    text = arabic_text.strip() if arabic_text.strip() else "بسم الله"

    prompt = (
        f"Arabic calligraphy art of the text '{text}', "
        f"rendered in {style_desc}, "
        f"with {fg} on {bg}, "
        f"{comp_desc}, "
        f"high detail, ultra sharp, 4k, luxurious Islamic art style"
    )
    return prompt


def generate_calligraphy(arabic_text, style, color_scheme, composition):
    """Generate Arabic calligraphy art via FLUX.1-schnell."""
    prompt = build_prompt(arabic_text, style, color_scheme, composition)
    w, h = 1024, 1024

    try:
        image = client.text_to_image(prompt, width=w, height=h)
        if not isinstance(image, Image.Image):
            image = Image.open(io.BytesIO(image)) if hasattr(image, "read") else Image.open(image)
        return image, "✅ Calligraphy generated!", prompt
    except Exception as e:
        img = Image.new("RGB", (w, h), BG_COLOR)
        d = ImageDraw.Draw(img)
        d.text((w // 4, h // 2), f"Error: {str(e)[:60]}", fill=ACCENT)
        return img, f"❌ Error: {str(e)}", prompt


# --- UI -----------------------------------------------------------------------
CSS = """
#dispatch-header h1 {
    color: #FFFFFF; font-size: 2.2rem; margin: 0;
    background: linear-gradient(90deg, #1FE0E6 0%, #FFFFFF 60%);
    -webkit-background-clip: text; -webkit-text-fill-color: transparent;
}
#dispatch-header p { color: #1FE0E6; font-size: 1.05rem; margin: 6px 0 0 0; }
.dispatch-footer { text-align: center; color: #8A8F9C; font-size: 0.9rem; padding-top: 8px; }
"""

with gr.Blocks(
    title="Dispatch AI — Arabic Calligraphy",
    theme=gr.themes.Base(
        primary_hue="cyan",
        secondary_hue="cyan",
        neutral_hue="slate",
        font=[gr.themes.GoogleFont("Inter"), "ui-sans-serif", "system-ui"],
    ).set(
        body_background_fill="#0A0F1A",
        body_background_fill_dark="#0A0F1A",
        body_text_color="#FFFFFF",
        body_text_color_dark="#FFFFFF",
        block_background_fill="#0E1424",
        block_background_fill_dark="#0E1424",
        block_border_color="#1FE0E6",
        block_border_width="1px",
        block_label_text_color="#1FE0E6",
        block_title_text_color="#1FE0E6",
        button_primary_background_fill="#1FE0E6",
        button_primary_background_fill_dark="#1FE0E6",
        button_primary_text_color="#0A0F1A",
        button_primary_border_color="#1FE0E6",
        input_background_fill="#0E1424",
        input_background_fill_dark="#0E1424",
        input_border_color="#1FE0E6",
        input_border_width="1px",
    ),
    css=CSS,
) as demo:
    with gr.Column(elem_id="dispatch-header"):
        gr.Markdown(
            """
            # Dispatch AI — Arabic Calligraphy
            Generate beautiful Arabic calligraphy art with FLUX.1-schnell · Dispatch AI (FZE) · UAE
            """
        )

    with gr.Row():
        with gr.Column(scale=1):
            arabic_input = gr.Textbox(
                label="Arabic Text",
                placeholder="اكتب النص هنا",
                value="بسم الله الرحمن الرحيم",
                lines=2,
                rtl=True,
            )
            style_select = gr.Dropdown(
                list(STYLES.keys()),
                label="Calligraphy Style",
                value="Thuluth",
            )
            color_select = gr.Dropdown(
                list(COLOR_SCHEMES.keys()),
                label="Color Scheme",
                value="Gold on Black",
            )
            composition_select = gr.Dropdown(
                list(COMPOSITIONS.keys()),
                label="Composition / Layout",
                value="Centered",
            )
            generate_btn = gr.Button("✨ Generate Calligraphy", variant="primary")
        with gr.Column(scale=2):
            output_image = gr.Image(
                label="Generated Calligraphy",
                type="pil",
                show_download_button=True,
            )
            status_box = gr.Textbox(label="Status", interactive=False)
            prompt_box = gr.Textbox(label="Generated Prompt (for debugging)", interactive=False, lines=3)

    gr.Markdown("### Example Arabic Prompts")
    gr.Examples(
        examples=[[ex] for ex in EXAMPLES_AR],
        inputs=arabic_input,
        label="Click an example to load it into the Arabic text box",
    )

    # Events
    generate_btn.click(
        generate_calligraphy,
        inputs=[arabic_input, style_select, color_select, composition_select],
        outputs=[output_image, status_box, prompt_box],
    )

    gr.Markdown(
        """
        <div class="dispatch-footer">
        © 2026 Dispatch AI (FZE) · UAE · License 10818 · Model: FLUX.1-schnell · Arabic Calligraphy Engine
        </div>
        """
    )

if __name__ == "__main__":
    demo.queue()
    demo.launch()