GEMINI LABJP
3.8LIVE — Two audio-to-audio models reached GA for the Live API: gemini-3.8-live as the low-latency default, and -extended-thinking for background reasoning mid-conversation09/30 — Thirteen days until gemini-omni-flash-preview shuts down. The replacement is gemini-omni-1.1-flash, so count your call sites before you swapMCP — A timeout written as ten minutes on the extension side is reportedly cutting out at one. Anyone handing long work to an MCP server runs straight into itNEW — When an AI function in Sheets refuses to generate, suspect where the file lives before you blame the 24-hour capGEM — When a Gem built for your team will not share, walk the admin settings and the Drive sharing settings in a set order10/16 — Twenty-nine days until Gemini 2.5 Pro, Flash and Flash-Lite shut down together. The path forward is the 3.5 Flash line3.8LIVE — Two audio-to-audio models reached GA for the Live API: gemini-3.8-live as the low-latency default, and -extended-thinking for background reasoning mid-conversation09/30 — Thirteen days until gemini-omni-flash-preview shuts down. The replacement is gemini-omni-1.1-flash, so count your call sites before you swapMCP — A timeout written as ten minutes on the extension side is reportedly cutting out at one. Anyone handing long work to an MCP server runs straight into itNEW — When an AI function in Sheets refuses to generate, suspect where the file lives before you blame the 24-hour capGEM — When a Gem built for your team will not share, walk the admin settings and the Drive sharing settings in a set order10/16 — Twenty-nine days until Gemini 2.5 Pro, Flash and Flash-Lite shut down together. The path forward is the 3.5 Flash line
Articles/Advanced
Advanced/2026-09-17Intermediate

The color label Gemini returned for the same wallpaper changed — and the model was not the reason

I counted color-label agreement across five ways of exporting the same wallpaper. Stripping the ICC profile was the worst of them. Here is how I pin the color space down before asking, and how I check the answers against a number I compute myself.

Gemini87Image understandingColor spaceWallpaper appPython47

Premium Article

I was classifying the new batch of ukiyo-e wallpapers late one evening when an image that had come back as blue the week before came back as gray. The prompt had not changed. The model was the same. The one thing I had changed was the tool I used to export the files.

It took me two nights to find the cause. It was not the model having an off day — it was the image I was handing over. More precisely, I had been discarding the one hint that tells a reader which color space those pixel values belong to.

So I lined up five ways of exporting the same picture and counted. The material is 120 new images from the wallpaper app I run as an indie developer.

Only the color field was moving

The first thing I did was narrow the drift. My classifier returns four fields: subject, composition, dominant color, and usage tags. I re-read them side by side to see which one was actually changing.

Subject and composition came back identical on a second pass. So did the usage tags. The only field that moved was the dominant color.

That settled the direction. Instead of rewriting the whole prompt, I could measure one field. Narrowing the scope is why 120 images across five export variants finished in a single night.

Output rarely drifts as a whole. Count the fields separately and the thing you need to fix tends to collapse into one place.

Five export variants, defined before any measuring

The conditions

The originals are 4K images in Display P3. I produced five variants from each, with the long edge normalized to 1,024 pixels so that resolution would not get mixed into the result.

  1. Converted to sRGB, saved as JPEG at quality 95 — this is my baseline
  2. Left in Display P3, ICC profile embedded, JPEG at quality 95
  3. Left in Display P3, ICC profile stripped, JPEG at quality 95
  4. Converted to sRGB, saved as PNG
  5. Converted to sRGB, saved as WebP at quality 80

Variant 3 is what I had actually been shipping. A profile is tens of kilobytes, and when you are trimming delivery size, it looks like free weight to drop.

The normalization itself is a few lines with Pillow's ImageCms.

# normalize_srgb.py — decide the color space yourself, before handing it over
from io import BytesIO
from PIL import Image, ImageCms
 
SRGB = ImageCms.createProfile("sRGB")
 
def to_srgb_jpeg(path: str, long_edge: int = 1024, quality: int = 95) -> bytes:
    img = Image.open(path)
    raw = img.info.get("icc_profile")
    if raw:
        # Only convert when a profile exists; converting an untagged image applies it twice
        src = ImageCms.ImageCmsProfile(BytesIO(raw))
        img = ImageCms.profileToProfile(img, src, SRGB, outputMode="RGB")
    else:
        # With no hint, sRGB is the only reasonable assumption. Log this branch
        img = img.convert("RGB")
    img.thumbnail((long_edge, long_edge), Image.LANCZOS)
    buf = BytesIO()
    # After conversion the reading is unambiguous whether or not a profile is attached
    img.save(buf, format="JPEG", quality=quality, optimize=True)
    return buf.getvalue()

profileToProfile rewrites the pixel values. Embedding a profile does not. Treating those two operations as the same thing is where my misreading started.

How the requests were sent

One image per request, same prompt, temperature pinned to 0, and the color restricted to a closed vocabulary of eight words. With free-form answers, wording differences creep in, and you can no longer tell whether the color changed or only the word for it did.

What counts as agreement

If a variant returned the same word as the baseline, I counted it as agreement. I also ran the baseline twice to measure its self-agreement. If the baseline itself drifts, there is nothing to compare against.

Thank you for reading this far.

Continue Reading

What follows includes implementation code, benchmarks, and practical content we hope you'll find useful. This site runs without ads — server and development costs are supported entirely by members like you. If it's been helpful, we'd be truly grateful for your support.

WHAT YOU'LL LEARN
You will be able to check, with 20 images from your own library, whether your export settings are changing what the model calls the color
You will be able to avoid the mistake that cost me two nights: the size optimization that strips metadata is the one that damages the judgment most
You will be able to put a closed color vocabulary and a self-computed reference value into your own pipeline as a cross-check
Secure payment via Stripe · Cancel anytime

Unlock This Article

Get full access to the rest of this article. Buy once, read anytime. This site is ad-free — your support goes directly toward keeping it running.

or
Unlock all articles with Membership →
Share

Thank You for Reading

Gemini Lab is ad-free, supported entirely by members like you. We publish practical guides daily with implementation code, benchmarks, and production-ready patterns. If you've found it useful, we'd love to have you on board.

  • Copy-paste ready implementation code
  • New advanced guides published daily
  • $5/mo or $15 for lifetime access
View Membership →

Related Articles

Advanced2026-07-10
My ADK Assistant Quietly Forgot a Deadline — Catching Compaction Memory Loss With a Recall Probe
Compacting conversation history in Google ADK with Gemini lowers cost, but it also erodes what your assistant remembers — silently. Here is how I built a recall probe to measure that loss, compared three compaction strategies against the same ledger, and stopped trading memory for tokens.
Advanced2026-06-27
Don't Ingest Gemini Deep Research Reports Blindly — A Citation-Verification Acceptance Gate for MCP-Grounded Research
Now that Deep Research connects to MCP servers and File Search, you can ground research on your own data. This builds an acceptance gate that verifies, before any automated ingest, whether each citation resolves to a trusted source — with an allowlist, a grounding-coverage ratio, and categorized reject reasons, all in working code.
Advanced2026-06-14
Switching Image Models Quietly Degrades Quality — A Gate That Catches It Without Manual Review
When you move image generation from preview to GA models, the API keeps returning 200 and quality slips silently. This is the three-layer gate I built to detect that drift without staring at every image: deterministic property checks, multimodal embedding similarity, and a Gemini judge, wired together in Python with thresholds and a cutover procedure.
📚RECOMMENDED BOOKS
Build a Large Language Model (From Scratch)
Sebastian Raschka
LLM Dev
Prompt Engineering for LLMs
Berryman & Ziegler
Prompting
AI Engineering
Chip Huyen
AI Eng
* Contains affiliate links