This commit is contained in:
Concept Agent
2026-05-15 18:02:38 +02:00
parent 72016728e2
commit 307e452251
175 changed files with 9316 additions and 0 deletions
+179
View File
@@ -0,0 +1,179 @@
"""
Lahr Carpet Cleaning — Service card image generator.
Generates 12 unique images for residential and commercial service cards.
Saves to: assets/images/services/
Run: python3 tools/gen-service-images.py
"""
import os
import sys
try:
from google import genai
from google.genai import types
except ImportError:
print("Installing google-genai...")
os.system(f"{sys.executable} -m pip install google-genai --quiet")
from google import genai
from google.genai import types
API_KEY = os.environ.get("GEMINI_API_KEY", "AIzaSyB_1p8KvaT_rdNJGPs8HKk8bKsvUlcL6Kg")
OUT_DIR = os.path.join(os.path.dirname(os.path.dirname(__file__)), "assets", "images", "services")
os.makedirs(OUT_DIR, exist_ok=True)
client = genai.Client(api_key=API_KEY)
IMAGES = [
# ── Residential ──────────────────────────────────────────────────────────
{
"name": "carpet-cleaning",
"prompt": (
"Wide shot of a large industrial stand-up hot water extraction machine being pushed across "
"a plush beige residential carpet. The machine is a heavy commercial-grade upright extractor "
"on wheels — tall, wide cleaning head at the base, long upright handle. "
"The carpet behind it transitions from dirty and matted to clean, bright, and fluffy. "
"Completely dry machine exterior, no steam, no water spraying anywhere. "
"Warm natural interior light. Ultra-realistic professional photography."
),
},
{
"name": "stairs-cleaning",
"prompt": (
"Wide cinematic shot of a carpeted residential staircase. Each step has clean, "
"bright plush carpet that looks freshly cleaned with visible extraction lines. "
"Modern upstate New York home interior, natural light from above, "
"warm wood banisters, no people, no equipment visible. "
"Professional interior photography, ultra-realistic."
),
},
{
"name": "upholstery-cleaning",
"prompt": (
"Close-up of a clean grey linen sofa cushion showing bright, lifted fabric texture "
"after professional upholstery cleaning. Half the cushion shows the before "
"(slightly soiled, flat fabric) and half shows the cleaned result (bright, fluffy, refreshed). "
"Natural window light, residential living room in background, no people, no equipment. "
"Ultra-realistic product photography."
),
},
{
"name": "floor-cleaning",
"prompt": (
"Wide shot of a gleaming hardwood floor in a modern residential home after professional "
"cleaning. The floor reflects soft natural window light, showing deep grain detail. "
"Contemporary furniture in background, no people, no cleaning equipment visible. "
"Professional interior photography, ultra-realistic."
),
},
{
"name": "area-rug-cleaning",
"prompt": (
"Overhead flat-lay shot of a large vibrant Persian or oriental area rug "
"with rich red, navy, and cream geometric patterns, looking freshly cleaned — "
"colors vivid, fibers lifted and bright. Hardwood floor beneath. "
"No people, no equipment, no water. Professional product photography, ultra-realistic."
),
},
{
"name": "add-ons",
"prompt": (
"Close-up macro shot of clean carpet fibers being lifted by a professional "
"grooming brush after hot water extraction cleaning. The fibers are bright, "
"fluffy, and standing upright. Warm light catches the texture. "
"No steam, no water, no people. Ultra-realistic macro photography."
),
},
# ── Commercial ───────────────────────────────────────────────────────────
{
"name": "vacation-rentals",
"prompt": (
"Bright, airy vacation rental living room in the Finger Lakes region of upstate New York. "
"Spotlessly clean cream carpet, contemporary furniture, large windows with lake views, "
"warm natural afternoon light. Inviting and fresh. No people, no equipment. "
"Professional real estate photography, ultra-realistic."
),
},
{
"name": "office-spaces",
"prompt": (
"Wide shot of a clean modern corporate office with freshly cleaned dark charcoal carpet "
"throughout. Open plan workspace, glass partitions, professional lighting. "
"Carpet shows neat vacuum lines indicating recent professional cleaning. "
"No people, no equipment. Professional architectural photography, ultra-realistic."
),
},
{
"name": "hotels-inns",
"prompt": (
"Elegant hotel corridor in a boutique upstate New York inn. Clean, plush patterned "
"carpet runner down the hallway with fresh vacuum lines. Warm sconce lighting, "
"wood paneling, framed art on walls. No people, no equipment. "
"Professional hospitality photography, ultra-realistic."
),
},
{
"name": "retail-showrooms",
"prompt": (
"Wide shot of an upscale retail showroom or winery tasting room in the Finger Lakes. "
"Clean, rich carpet throughout, warm lighting, product displays on shelves. "
"Carpet looks freshly extracted — bright and spotless. "
"No people, no equipment. Professional commercial interior photography, ultra-realistic."
),
},
{
"name": "property-management",
"prompt": (
"View across three clean apartment living rooms in sequence, each showing "
"spotlessly clean beige carpet with fresh vacuum lines after professional cleaning. "
"Bright, neutral interiors ready for new tenants. Natural light, no furniture, "
"no people, no equipment. Professional real estate photography, ultra-realistic."
),
},
{
"name": "commercial-overview",
"prompt": (
"Professional carpet cleaning technician in a plain black shirt, shown from the side, "
"pushing a large industrial stand-up hot water extraction machine through a bright commercial "
"building lobby. The machine is a heavy commercial-grade upright extractor on wheels — "
"tall, wide cleaning head, long handle. Clean carpet visible. No steam, no water spraying, "
"no face visible. Professional editorial photography, ultra-realistic."
),
},
]
def generate():
saved = []
total = len(IMAGES)
for i, item in enumerate(IMAGES, 1):
out_path = os.path.join(OUT_DIR, f"{item['name']}.jpg")
print(f"[{i}/{total}] Generating {item['name']}...")
try:
resp = client.models.generate_images(
model="imagen-4.0-generate-001",
prompt=item["prompt"],
config=types.GenerateImagesConfig(
number_of_images=1,
aspect_ratio="4:3",
output_mime_type="image/jpeg",
safety_filter_level="block_low_and_above",
),
)
if resp.generated_images:
img_bytes = resp.generated_images[0].image.image_bytes
with open(out_path, "wb") as f:
f.write(img_bytes)
print(f" Saved {out_path} ({len(img_bytes)//1024}KB)")
saved.append(item["name"])
else:
print(f" No image returned for {item['name']}")
except Exception as e:
print(f" Error on {item['name']}: {e}")
return saved
if __name__ == "__main__":
saved = generate()
print(f"\nDone. {len(saved)}/{len(IMAGES)} images saved to assets/images/services/")
if saved:
print("Generated:", ", ".join(saved))