File size: 16,434 Bytes
a8aea21
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
#!/usr/bin/env python3
"""

test_checkpoint.py

==================

Two-Stage Poster Generation Pipeline β€” SDXL Artwork + PIL Typography



Stage 1  Generate pure visual artwork with SDXL + Campus AI LoRA.

         Prompts describe ONLY visual atmosphere β€” zero text references.

         guidance_scale=7.5 ensures the negative prompt suppresses all

         hallucinated text/watermarks from the diffusion output.



Stage 2  PIL Compositor overlays pixel-perfect typography on the raw artwork.



Usage:

    python test_checkpoint.py



Outputs in output/test_generations/:

    <slug>_artwork.png   β€” raw SDXL output, no text

    <slug>_poster.png    β€” final composited poster



Per-poster controls:

    text_position  "top" | "center" | "bottom" | "auto"

                   Set based on where the artwork has clean negative space.

    scrim          True  for dark/busy artworks β€” adds contrast under text.

                   False for vivid/bright artworks β€” keep colours untouched.

"""

from __future__ import annotations

import os
import sys

import torch
from pathlib import Path

sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
from poster_compositor import composite_poster, ensure_fonts


# ---------------------------------------------------------------------------
# Shared negative prompt
# ---------------------------------------------------------------------------
# Explicitly blocks ALL forms of text/typography from the raw artwork.
# garbled_text and illegible_text added specifically to kill LoRA artefacts
# like BOMIELLOOOKD / OULSTECS seen in previous generations.

_NEG = (
    "text, words, letters, typography, fonts, captions, labels, watermark, "
    "signature, logo, banner, title, heading, writing, written text, "
    "illegible text, garbled text, gibberish text, distorted words, "
    "random letters, fake words, blurry, low quality, deformed, ugly, "
    "disfigured, oversaturated, bad anatomy, cropped, out of frame"
)


# ---------------------------------------------------------------------------
# Poster definitions
# ---------------------------------------------------------------------------

POSTERS: list[tuple[str, str, dict]] = [

    # ── Freshers Party ──────────────────────────────────────────────────────
    (
        "freshers_party",

        "campus_ai_poster  Vibrant freshers welcome party background.  "
        "Confetti explosion in electric blue and neon purple raining from above.  "
        "Disco ball casting prismatic reflections across a dark concert stage.  "
        "Bokeh light circles in hot pink and cyan filling the frame.  "
        "Bollywood dance-floor energy with glitter dust in a single spotlight beam.  "
        "Shallow depth of field, cinematic wide-angle composition.  "
        "No text, no signs, no banners anywhere in the scene.",

        dict(
            title          = "Freshers Bash 2026",
            subtitle       = "Welcome to the Jungle, First Years!",
            date           = "August 22, 2026  β€’  6 PM Onwards",
            venue          = "Open Air Theatre, DTU",
            organizer      = "Student Council 2026–27",
            accent_color   = "#E040FB",
            style          = "bold",
            text_position  = "bottom",
            scrim          = True,
        ),
    ),

    # ── Navratri Garba ──────────────────────────────────────────────────────
    (
        "navratri_garba",

        "campus_ai_poster  Stunning Navratri Garba night celebration background.  "
        "Swirling dandiya sticks and ghagra choli silhouettes mid-spin viewed from above.  "
        "Warm saffron, deep crimson, and gold falling flower petals.  "
        "Intricate mirror-work embroidery and marigold garland borders framing the scene.  "
        "Glowing earthen diyas reflecting off a polished stone floor.  "
        "Rich festive atmosphere, painterly detail, vibrant colour contrast.  "
        "No text, no signs, no labels anywhere in the scene.",

        dict(
            title          = "Garba Raas Night",
            subtitle       = "Nine Nights of Dandiya & Dance",
            date           = "October 2–10, 2026",
            venue          = "College Ground, SVNIT Surat",
            organizer      = "Gujarat Cultural Committee",
            accent_color   = "#FF6F00",
            style          = "elegant",
            text_position  = "bottom",
            scrim          = False,
        ),
    ),

    # ── Coding Hackathon ────────────────────────────────────────────────────
    (
        "coding_hackathon",

        "campus_ai_poster  Dark futuristic hackathon coding environment background.  "
        "Multiple holographic screens floating in 3-D space with scrolling green "
        "terminal animations and binary rain patterns.  "
        "Glowing cyan circuit-board traces on a deep black background.  "
        "Keyboard and laptop silhouettes lit from below by a cool blue glow.  "
        "High-contrast, ultra-sharp, cyberpunk aesthetic.  "
        "No text, no readable characters, no words anywhere in the scene.",

        dict(
            title          = "Code-a-thon 4.0",
            subtitle       = "36 Hours.  No Sleep.  Pure Code.",
            date           = "January 18–19, 2026",
            venue          = "CS Lab 301, IIT Bombay",
            organizer      = "WnCC & DevClub",
            accent_color   = "#00E676",
            style          = "bold",
            text_position  = "bottom",
            scrim          = True,
        ),
    ),

    # ── Blood Donation Camp ─────────────────────────────────────────────────
    (
        "blood_donation",

        "campus_ai_poster  Warm heartfelt blood donation awareness background.  "
        "A large red blood drop with a heartbeat ECG line running through its center.  "
        "Clean white and soft crimson minimalist medical composition.  "
        "Two open hands gently cupping the drop from below.  "
        "Gentle radial light bloom.  Compassionate, hopeful healthcare aesthetic.  "
        "No text, no words, no labels in the scene.",

        dict(
            title          = "Donate Blood, Save Lives",
            subtitle       = "NSS Blood Donation Camp",
            date           = "March 5, 2026  β€’  9 AM – 4 PM",
            venue          = "Health Centre, NIT Trichy",
            organizer      = "NSS Unit & Red Cross Society",
            accent_color   = "#D32F2F",
            style          = "modern",
            text_position  = "bottom",
            scrim          = False,
        ),
    ),

    # ── Farewell ────────────────────────────────────────────────────────────
    (
        "farewell",

        "campus_ai_poster  Sentimental farewell celebration background.  "
        "Golden fairy lights strung across a twilight campus courtyard.  "
        "Graduation caps thrown upward against a warm amber-peach sunset sky.  "
        "Bokeh spheres in champagne gold and soft peach.  "
        "Petals falling slowly through the air from above.  "
        "Nostalgic, bittersweet, and celebratory mood.  Warm film-grain texture.  "
        "No text, no banners, no words in the scene.",

        dict(
            title          = "Alvida β€” Farewell 2026",
            subtitle       = "For the Batch That Made It Legendary",
            date           = "May 15, 2026  β€’  5 PM",
            venue          = "Main Auditorium, NSUT",
            organizer      = "Third Year Organizing Committee",
            accent_color   = "#FFD54F",
            style          = "elegant",
            text_position  = "bottom",
            scrim          = False,
        ),
    ),

    # ── Annual Cultural Fest ─────────────────────────────────────────────────
    (
        "annual_fest",

        "campus_ai_poster  Epic grand annual college cultural fest background.  "
        "Massive paint-splash explosion in rainbow neon colours filling the entire frame.  "
        "Fireworks bursting above a packed outdoor main stage.  "
        "Laser beams sweeping over a roaring silhouette crowd.  "
        "Smoke machines and confetti cannons firing simultaneously.  "
        "Maximum energy, blockbuster festival scale, ultra-vivid colour grading.  "
        "Absolutely no text, no stage signs, no banners, no readable characters.",

        dict(
            title          = "MOKSHA 2026",
            subtitle       = "The Biggest College Fest in India",
            date           = "February 14–16, 2026",
            venue          = "NSUT Main Campus, Dwarka",
            organizer      = "Moksha Organizing Committee",
            accent_color   = "#FF1744",
            style          = "bold",
            text_position  = "bottom",
            scrim          = True,
        ),
    ),

    # ── Robotics Competition ─────────────────────────────────────────────────
    (
        "robotics_competition",

        "campus_ai_poster  Futuristic robotics competition arena background.  "
        "A sleek industrial robot arm mid-motion under dramatic blue-white spotlights.  "
        "Metallic gears, pistons, and carbon-fibre surface textures.  "
        "Electric sparks flying off welded joints.  Dark smoke and industrial haze.  "
        "High-contrast dramatic lighting, mechanical precision aesthetic.  "
        "No text, no labels, no signage anywhere in the scene.",

        dict(
            title          = "RoboWars 2026",
            subtitle       = "Build It.  Break It.  Win It.",
            date           = "March 22, 2026",
            venue          = "Innovation Hub, BITS Pilani",
            organizer      = "Robotics & Automation Society",
            accent_color   = "#40C4FF",
            style          = "modern",
            text_position  = "bottom",
            scrim          = True,
        ),
    ),

    # ── Standup Comedy Night ─────────────────────────────────────────────────
    (
        "standup_comedy",

        "campus_ai_poster  Moody open-mic comedy night stage background.  "
        "Single golden spotlight cone hitting a lone microphone stand centre stage.  "
        "Deep maroon velvet curtains framing the wings on both sides.  "
        "Brick wall texture visible at the back β€” classic comedy club look.  "
        "Warm amber footlights and a faint laughing crowd silhouette at the bottom.  "
        "Intimate, atmospheric, slightly gritty feel.  "
        "No text, no words, no chalk board writing, no signs anywhere.",

        dict(
            title          = "Laugh Riot 2026",
            subtitle       = "Open Mic Comedy Night",
            date           = "April 5, 2026  β€’  7 PM",
            venue          = "Black Box Theatre, Miranda House",
            organizer      = "The Comedy Collective",
            accent_color   = "#FFAB40",
            style          = "modern",
            text_position  = "top",      # mic + spotlight fill center/bottom
            scrim          = True,
        ),
    ),

    # ── Diwali Celebration ───────────────────────────────────────────────────
    (
        "diwali",

        "campus_ai_poster  Magical Diwali festival night background.  "
        "Hundreds of glowing earthen diyas arranged in concentric circles on dark stone.  "
        "Fireworks bursting in gold, silver, and emerald green overhead.  "
        "Intricate rangoli patterns in vibrant pink, blue, and orange surrounding the diyas.  "
        "Warm golden bokeh light spheres floating throughout.  "
        "Festive, divine, deeply traditional Indian atmosphere.  "
        "No text, no words, no labels anywhere in the scene.",

        dict(
            title          = "Diwali Utsav 2026",
            subtitle       = "Festival of Lights on Campus",
            date           = "October 20, 2026  β€’  6 PM",
            venue          = "Central Lawn, IIT Delhi",
            organizer      = "Cultural Committee & NSS",
            accent_color   = "#FFD700",
            style          = "elegant",
            text_position  = "top",      # rangoli / diyas fill bottom beautifully
            scrim          = False,
        ),
    ),

]


# ---------------------------------------------------------------------------
# Pipeline
# ---------------------------------------------------------------------------

def _load_pipeline(base_id: str, lora_dir: str, lora_file: str):
    from diffusers import AutoPipelineForText2Image, DPMSolverMultistepScheduler

    print("  Loading SDXL base model ...")
    pipe = AutoPipelineForText2Image.from_pretrained(
        base_id,
        torch_dtype     = torch.float16,
        variant         = "fp16",
        use_safetensors = True,
    ).to("cuda")

    # DPM++ 2M Karras β€” sharper outputs, better prompt adherence than DDPM
    pipe.scheduler = DPMSolverMultistepScheduler.from_config(
        pipe.scheduler.config,
        use_karras_sigmas = True,
    )

    lora_path = os.path.join(lora_dir, lora_file)
    if os.path.exists(lora_path):
        pipe.load_lora_weights(lora_dir, weight_name=lora_file, adapter_name="campus_poster")
        pipe.set_adapters(["campus_poster"], adapter_weights=[1.0])
        print(f"  LoRA loaded  β†’  {lora_path}")
    else:
        print(f"  WARNING: LoRA not found at {lora_path}  β€”  using base SDXL only")

    return pipe


def generate_posters() -> None:
    out_dir   = Path("output/test_generations")
    lora_dir  = "models/sdxl/checkpoints/campus_ai_poster_sdxl_phase3"
    lora_file = "campus_ai_poster_sdxl_phase3.safetensors"
    base_id   = "stabilityai/stable-diffusion-xl-base-1.0"

    out_dir.mkdir(parents=True, exist_ok=True)

    print("=" * 60)
    print("  CAMPUS AI  β€”  TWO-STAGE POSTER PIPELINE")
    print("=" * 60)

    print("\n[Stage 0]  Downloading / verifying fonts ...")
    ensure_fonts()

    print("\n[Stage 1]  Loading SDXL + Campus AI LoRA ...")
    pipe = _load_pipeline(base_id, lora_dir, lora_file)

    print(f"\n[Stage 2]  Generating {len(POSTERS)} posters ...\n")

    for slug, artwork_prompt, text_cfg in POSTERS:
        label = slug.upper().replace("_", " ")
        print(f"  🎨  {label}")

        artwork = pipe(
            artwork_prompt,
            negative_prompt     = _NEG,
            num_inference_steps = 35,   # +5 steps for cleaner detail
            guidance_scale      = 7.5,  # stronger negative adherence β€” kills hallucinated text
        ).images[0]

        artwork_path = out_dir / f"{slug}_artwork.png"
        artwork.save(artwork_path)
        print(f"       artwork  β†’  {artwork_path}")

        final = composite_poster(artwork, **text_cfg)
        poster_path = out_dir / f"{slug}_poster.png"
        final.save(poster_path)
        print(f"       poster   β†’  {poster_path}\n")

    del pipe
    torch.cuda.empty_cache()

    print("=" * 60)
    print(f"  βœ…  Done.  All outputs in  {out_dir}/")
    print("       *_artwork.png  β†’  raw SDXL art, no text")
    print("       *_poster.png   β†’  final composited poster")
    print("=" * 60)


if __name__ == "__main__":
    generate_posters()