Download tests/make_test_images.py from EverPaper/embeddinggemma-2-coreai: direct link, hf CLI and curl.
- Browser
- Download file 9.81 kB
-
https://huggingface.co/EverPaper/embeddinggemma-2-coreai/resolve/main/tests/make_test_images.py
- Command line
-
hf download hf://EverPaper/embeddinggemma-2-coreai/tests/make_test_images.py
-
curl -L -o make_test_images.py https://huggingface.co/EverPaper/embeddinggemma-2-coreai/resolve/main/tests/make_test_images.py
9.81 kB
| #!/usr/bin/env python3 | |
| # Copyright 2026 Everpaper. Licensed under the Apache License, Version 2.0 (see ../LICENSE). | |
| """Render the small fictional image set shipped in tests/images/ (Pillow only, no randomness): a bar chart, a phone | |
| login screen, a slide, an invoice, a flow diagram, a sunset scene (JPEG), a red circle, an RGBA icon, a grayscale | |
| letter, a palette chart, plus two edge-size images (7x5 and 1x300 px) that exercise the resampler's upscale and | |
| extreme-aspect paths. All names, companies and numbers are invented. | |
| python3 make_test_images.py [--out images] -> <out>/*.png|jpg + <out>/manifest.json | |
| The output is repeatable on one machine but NOT byte-identical across machines: text is drawn with the first | |
| system font found in FONT_PATHS (or Pillow's built-in font), and glyph rasterization, PNG compression and JPEG | |
| encoding depend on the font files and on the Pillow / FreeType / zlib / libjpeg versions. The shipped files in | |
| tests/images/ are the reference: image-smoke-reference.json and preprocess-cases.json were computed from them, so | |
| regenerate those two fixtures (make_image_smoke_reference.py, make_preprocess_cases.py) if you regenerate the images. | |
| """ | |
| from __future__ import annotations | |
| import argparse | |
| import json | |
| from pathlib import Path | |
| from PIL import Image, ImageDraw, ImageFont | |
| FONT_PATHS = ["/System/Library/Fonts/Helvetica.ttc", "/System/Library/Fonts/Supplemental/Arial.ttf", | |
| "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf"] | |
| def font(size: int): | |
| for p in FONT_PATHS: | |
| try: | |
| return ImageFont.truetype(p, size) | |
| except OSError: | |
| continue | |
| return ImageFont.load_default() | |
| def chart_bar(w=640, h=400): | |
| im = Image.new("RGB", (w, h), "white") | |
| d = ImageDraw.Draw(im) | |
| d.text((20, 12), "Lumen lamps - units sold per city, Q3", fill="black", font=font(20)) | |
| cities = ["Port Avelin", "North Corra", "Westmere", "Lake Tamsin", "Oskaro"] | |
| vals = [412, 263, 538, 190, 347] | |
| cols = ["#4C78A8", "#F58518", "#54A24B", "#E45756", "#72B7B2"] | |
| d.line([(60, h - 50), (w - 20, h - 50)], fill="black", width=2) | |
| d.line([(60, 50), (60, h - 50)], fill="black", width=2) | |
| bw = (w - 100) // len(cities) | |
| for i, (c, v, col) in enumerate(zip(cities, vals, cols)): | |
| x0 = 70 + i * bw | |
| d.rectangle([x0, h - 50 - v * 0.5, x0 + bw - 20, h - 50], fill=col) | |
| d.text((x0, h - 44), c, fill="black", font=font(13)) | |
| d.text((x0 + 5, h - 50 - v * 0.5 - 18), str(v), fill="black", font=font(13)) | |
| return im | |
| def ui_login(w=390, h=844): | |
| im = Image.new("RGB", (w, h), "#111418") | |
| d = ImageDraw.Draw(im) | |
| d.rounded_rectangle([40, 160, w - 40, 300], 24, fill="#1d2229") | |
| d.text((60, 180), "Welcome back", fill="white", font=font(28)) | |
| d.text((60, 230), "Sign in to Tidal Boards", fill="#9aa4b1", font=font(16)) | |
| for i, label in enumerate(["Email", "Password"]): | |
| y = 340 + i * 90 | |
| d.rounded_rectangle([40, y, w - 40, y + 56], 14, fill="#1d2229", outline="#2f3842") | |
| d.text((56, y + 18), label, fill="#6b7682", font=font(16)) | |
| d.rounded_rectangle([40, 540, w - 40, 596], 14, fill="#2f6fed") | |
| d.text((150, 556), "Sign in", fill="white", font=font(18)) | |
| d.text((110, 620), "Forgot your password?", fill="#9aa4b1", font=font(14)) | |
| return im | |
| def slide(w=1280, h=720): | |
| im = Image.new("RGB", (w, h), "#f6f3ec") | |
| d = ImageDraw.Draw(im) | |
| d.rectangle([0, 0, w, 90], fill="#264653") | |
| d.text((50, 25), "Nimbus tents: 2027 launch plan", fill="white", font=font(36)) | |
| bullets = ["Three sizes, one pole system", "Pre-orders open in March", "Retail partners in six cities", | |
| "Target: 18,000 units in the first season"] | |
| for i, b in enumerate(bullets): | |
| d.ellipse([70, 160 + i * 90, 90, 180 + i * 90], fill="#2a9d8f") | |
| d.text((110, 150 + i * 90), b, fill="#222", font=font(30)) | |
| d.text((w - 260, h - 50), "slide 4 of 12", fill="#777", font=font(18)) | |
| return im | |
| def doc_invoice(w=595, h=842): | |
| im = Image.new("RGB", (w, h), "white") | |
| d = ImageDraw.Draw(im) | |
| d.text((40, 40), "INVOICE No. 2027-0418", fill="black", font=font(22)) | |
| d.text((40, 80), "Quill Pens Ltd., 12 Harbour Lane, Port Avelin", fill="black", font=font(13)) | |
| d.text((40, 100), "Bill to: Westmere Public Library", fill="black", font=font(13)) | |
| y = 160 | |
| d.line([(40, y), (w - 40, y)], fill="black") | |
| rows = [("Fountain pen, steel nib", 24, "18.00"), ("Ink cartridges (box of 50)", 6, "9.50"), ("Gift boxes", 24, "2.20"), | |
| ("Shipping", 1, "14.00")] | |
| for name, qty, price in rows: | |
| y += 30 | |
| d.text((40, y), name, fill="black", font=font(13)) | |
| d.text((380, y), str(qty), fill="black", font=font(13)) | |
| d.text((460, y), price, fill="black", font=font(13)) | |
| y += 50 | |
| d.line([(40, y), (w - 40, y)], fill="black") | |
| d.text((380, y + 15), "Total: 555.80", fill="black", font=font(15)) | |
| d.text((40, h - 80), "Payment within 30 days. Thank you for your order.", fill="black", font=font(12)) | |
| return im | |
| def diagram_flow(w=800, h=500): | |
| im = Image.new("RGB", (w, h), "white") | |
| d = ImageDraw.Draw(im) | |
| boxes = [("Order received", 60, 200), ("Check stock", 300, 200), ("Pack", 540, 120), ("Back-order", 540, 280)] | |
| for t, x, y in boxes: | |
| d.rounded_rectangle([x, y, x + 180, y + 70], 12, fill="#dbeafe", outline="#1e3a8a", width=2) | |
| d.text((x + 15, y + 25), t, fill="#1e3a8a", font=font(17)) | |
| for a, b in [((240, 235), (300, 235)), ((480, 220), (540, 155)), ((480, 250), (540, 315))]: | |
| d.line([a, b], fill="#1e3a8a", width=3) | |
| d.polygon([b, (b[0] - 12, b[1] - 6), (b[0] - 12, b[1] + 6)], fill="#1e3a8a") | |
| d.text((320, 60), "Fulfilment flow", fill="black", font=font(24)) | |
| return im | |
| def scene_sunset(w=800, h=533): | |
| im = Image.new("RGB", (w, h)) | |
| d = ImageDraw.Draw(im) | |
| for y in range(h): | |
| t = y / h | |
| if t < 0.6: | |
| c = (int(40 + 200 * t / 0.6), int(60 + 90 * t / 0.6), int(120 - 80 * t / 0.6)) | |
| else: | |
| c = (int(20 + 30 * (t - 0.6) / 0.4), int(50 + 40 * (t - 0.6) / 0.4), int(90 + 60 * (t - 0.6) / 0.4)) | |
| d.line([(0, y), (w, y)], fill=c) | |
| d.ellipse([w // 2 - 60, int(h * 0.6) - 60, w // 2 + 60, int(h * 0.6) + 60], fill="#ffb347") | |
| d.rectangle([0, int(h * 0.6), w, h], fill=None) | |
| for i in range(0, w, 40): | |
| d.line([(i, int(h * 0.62) + (i % 80) // 20), (i + 24, int(h * 0.62) + (i % 80) // 20)], fill="#ffd27f", width=2) | |
| return im | |
| def shape_red_circle(w=300, h=300): | |
| im = Image.new("RGB", (w, h), "white") | |
| ImageDraw.Draw(im).ellipse([50, 50, 250, 250], fill="#d62828") | |
| return im | |
| def icon_rgba(w=256, h=256): | |
| im = Image.new("RGBA", (w, h), (0, 0, 0, 0)) | |
| d = ImageDraw.Draw(im) | |
| d.rounded_rectangle([20, 20, 236, 236], 48, fill=(47, 111, 237, 255)) | |
| d.polygon([(100, 75), (100, 181), (185, 128)], fill=(255, 255, 255, 255)) | |
| return im | |
| def gray_letter(w=600, h=800): | |
| im = Image.new("L", (w, h), 245) | |
| d = ImageDraw.Draw(im) | |
| lines = ["Dear neighbours,", "", "The community garden on Fern Street reopens on the first Saturday of May.", | |
| "Plots are assigned in the order of the sign-up sheet at the library.", "Tools stay in the shed; please", | |
| "return them before dusk.", "", "With thanks, the garden committee"] | |
| for i, l in enumerate(lines): | |
| d.text((50, 60 + i * 32), l, fill=20, font=font(16)) | |
| return im | |
| def palette_chart(w=500, h=320): | |
| im = Image.new("RGB", (w, h), "white") | |
| d = ImageDraw.Draw(im) | |
| d.text((20, 10), "Sales channel share", fill="black", font=font(18)) | |
| start = 0 | |
| for frac, col in [(0.45, "#1b9e77"), (0.3, "#d95f02"), (0.25, "#7570b3")]: | |
| d.pieslice([120, 60, 380, 300], start, start + frac * 360, fill=col) | |
| start += frac * 360 | |
| return im.quantize(16) | |
| def build(out: Path) -> list[dict]: | |
| out.mkdir(parents=True, exist_ok=True) | |
| items = [] | |
| def save(name, im, query, fmt="PNG", **kw): | |
| fn = f"{name}.{'jpg' if fmt == 'JPEG' else 'png'}" | |
| im.save(out / fn, format=fmt, **kw) | |
| with Image.open(out / fn) as chk: | |
| items.append(dict(name=name, file=fn, query=query, width=chk.width, height=chk.height, mode=chk.mode, lossy=fmt == "JPEG")) | |
| save("chart_bar", chart_bar(), "bar chart of lamp units sold per city") | |
| save("ui_login", ui_login(), "dark mobile login screen with email and password fields") | |
| save("slide_launch", slide(), "presentation slide about a tent product launch plan") | |
| save("doc_invoice", doc_invoice(), "invoice for fountain pens and ink cartridges") | |
| save("diagram_flow", diagram_flow(), "flow diagram of order fulfilment steps") | |
| save("scene_sunset", scene_sunset(), "sunset over the sea with an orange sun", fmt="JPEG", quality=90) | |
| save("shape_red_circle", shape_red_circle(), "a red circle on a white background") | |
| save("icon_rgba", icon_rgba(), "blue rounded app icon with a white play symbol") | |
| save("gray_letter", gray_letter(), "letter about a community garden reopening") | |
| save("palette_chart", palette_chart(), "pie chart of sales channel share") | |
| save("edge_tiny_7x5", shape_red_circle().resize((7, 5), Image.BICUBIC), "a red circle on a white background") | |
| save("edge_strip_1x300", ui_login().resize((1, 300), Image.BICUBIC), "a thin vertical strip") | |
| return items | |
| def main() -> None: | |
| ap = argparse.ArgumentParser(description=__doc__.splitlines()[0]) | |
| ap.add_argument("--out", default=str(Path(__file__).resolve().parent / "images")) | |
| args = ap.parse_args() | |
| items = build(Path(args.out)) | |
| (Path(args.out) / "manifest.json").write_text(json.dumps(items, indent=1) + "\n") | |
| print(len(items), "images ->", args.out) | |
| if __name__ == "__main__": | |
| main() | |