Asking an AI "what is this?" about an image you spent real time making is a stranger experience than I expected.
Normally I hand Gemini Vision wallpaper assets or UI screenshots. But when I handed it pieces I'd made with deliberate intent, what it would catch and what it would drop felt genuinely worth testing. Here's what I found after experimenting from late 2025 through early 2026.
The 4 Artworks I Gave to Gemini Vision
I deliberately chose 4 pieces from my portfolio to cover a range of interpretive scenarios:
- Work A: An abstract piece on the theme of light diffraction. Colors extracted from photos taken at a Shinto shrine, digitally reconstructed
- Work B: A long-exposure photograph capturing crowd movement. Intended to visualize collective psychology
- Work C: A composition heavy on negative space. Features textures that mimic washi (Japanese paper)
- Work D: A pattern-based piece that performs strongly in my wallpaper app — one of the series users select most often
I spread the selection across works with clear intent, multiple interpretive layers, concealed intent, and commercial success — to see how Gemini handles each.
The Analysis Code (Python)
I used Gemini 2.5 Flash for all four analyses. Flash is fast and cost-effective for batch image work.
import google.generativeai as genai
from pathlib import Path
import json, base64
genai.configure(api_key="YOUR_GEMINI_API_KEY")
model = genai.GenerativeModel("gemini-2.5-flash")
def analyze_artwork(image_path: str, mode: str = "general") -> dict:
"""Analyze an artwork image using Gemini Vision."""
prompts = {
"general": """
Analyze this image visually. Respond in JSON with these fields:
- "dominant_colors": 3-5 dominant colors (hex code + name)
- "composition_style": Describe the composition in 3 sentences
- "emotional_tone": The emotional tone (e.g., introspective, tense, calm)
- "visual_focus": Where does the viewer's eye go first?
- "cultural_hints": Any cultural or regional elements visible?
- "keywords": 5-7 English keywords usable as tags
""",
"wallpaper_fit": """
Evaluate this image as a smartphone wallpaper. Respond in JSON:
- "suitability_score": Score 1-10
- "target_mood": Ideal user mood or situation for this wallpaper
- "icon_readability": Impact on icon visibility (good/average/poor)
- "suggested_category": Suggested wallpaper category
- "improvement_hints": Any improvement suggestions (if any)
"""
}
image_bytes = Path(image_path).read_bytes()
encoded = base64.b64encode(image_bytes).decode()
ext = Path(image_path).suffix.lower()
mime_map = {
".jpg": "image/jpeg", ".jpeg": "image/jpeg",
".png": "image/png", ".webp": "image/webp"
}
mime_type = mime_map.get(ext, "image/jpeg")
response = model.generate_content([
prompts[mode],
{"mime_type": mime_type, "data": encoded}
])
text = response.text
start, end = text.find("{"), text.rfind("}") + 1
if start != -1 and end > start:
return json.loads(text[start:end])
return {"raw_response": text}
# Example usage
result = analyze_artwork("artwork_a.jpg", "general")
print(json.dumps(result, indent=2))
# Expected output:
# {
# "dominant_colors": [{"hex": "#F5E6C8", "name": "warm white"}, ...],
# "emotional_tone": "introspective, quiet",
# "visual_focus": "slightly above center"
# }Each image took 1.5–3 seconds and cost roughly $0.00002 per image (Flash pricing, May 2026). Light enough to run a batch without thinking about it.
What It Got Right, and What It Missed
Here's the honest breakdown:
Work A (light diffraction, abstract): The analysis was surprisingly accurate. The 5 dominant colors matched my intent closely, and the emotional tone came back as "introspective, quiet" — which fits. But what I'd actually intended was a taut tension underneath the calm. The surface stillness was detected; the tension beneath it was not.
Work B (crowd movement, long exposure): This was the most interesting result. Gemini identified "where the viewer's eye goes first" as the light source in the upper left — not the central movement I intended. Looking at the piece again with fresh eyes, there actually is a gravitational pull toward that corner. The AI surfaced a compositional element I hadn't consciously noticed.
Work C (negative space, washi texture): Keywords returned included "minimalism," "Japanese aesthetic," "meditative." Not bad. But the wallpaper suitability score came in at 6/10, with "icon readability: average." The art reading was reasonable, but it was conservative about functional fitness as a wallpaper — more cautious than I would have been.
Work D (pattern series, commercial hit): Wallpaper suitability: 9/10. "target_mood: relaxing for everyday use." "suggested_category: Nature / Texture." This aligned closely with the actual category data from my app. It was a useful confirmation that the AI's commercial instincts are calibrated reasonably well.
Practical Applications for My Wallpaper App
After this experiment, I integrated Gemini Vision into two parts of my workflow.
Auto-generating App Store descriptions
Writing individual descriptions for wallpaper images was a time sink. Now I generate them from the Vision analysis:
def generate_app_description(analysis: dict, locale: str = "en") -> str:
"""Generate App Store copy from Vision analysis output."""
model = genai.GenerativeModel("gemini-2.5-flash")
if locale == "en":
prompt = f"""
Write a 50-word App Store description for a wallpaper app.
Based on this analysis: {json.dumps(analysis)}
Evoke the scene where someone would use this wallpaper. Include natural SEO keywords.
Avoid excessive promotional language.
"""
else: # ja
prompt = f"""
以下の分析データをもとに、壁紙アプリ向けの日本語説明文を 80 字前後で書いてください。
ユーザーが使うシーンを想起させ、SEO キーワードを自然に含める形で。
分析データ: {json.dumps(analysis, ensure_ascii=False)}
"""
return model.generate_content(prompt).text.strip()The output tends to describe "a user's morning with this wallpaper" rather than the artwork itself — a user-facing perspective I don't naturally write from.
Auto-tagging and performance prediction
Using suggested_category and keywords together, the auto-tagging accuracy sits at around 85–90%, with me reviewing the remaining 10–15%. I also matched suitability_score against actual download data: works scoring 7 or above consistently performed better. It's not a perfect predictor, but it works as a first-pass filter. For a detailed look at the implementation, the wallpaper auto-categorization guide covers this in depth.
Where Gemini Vision Falls Short
Worth being honest about the limits.
It can't read artistic intent: Gemini reads form and color well, but the conceptual meaning behind a piece doesn't come through. The theme of "the structure of collective psychology" in Work B never appeared in any analysis output. For interpretations that require cultural context, creator background, or conceptual knowledge, human judgment is still necessary.
It conflates artistic value with functional value: Whether something works as a wallpaper and whether it works as art are two different questions. Gemini answers the first question reasonably. It struggles with the second.
It can't capture the quality of light: Hand it the kind of visual experience that resists verbal description, and it comes back as "glare effect" or "lens flare like pattern." The functional description lands, but the core of the experience doesn't. This is a confirmation, not a complaint. Knowing exactly where the boundary sits makes the tool more useful.
Turning Inaccuracy Into Production Feedback — How to Frame the Question
So far this has been about getting Vision to analyze. There's a step beyond that: getting it to question back. "Analyze this image" only ever returns a flat description. To get language worth having as a maker, I had to change the shape of the question itself.
Three framings earned their place:
- Ask for gaze order: "List where the eye goes first, second, and last." This surfaces a directional bias you've stopped noticing.
- Ask for collisions: "Which elements in this frame pull against each other?" Unintended tension and dissonance become visible.
- Ask for associations: "Name three places, times, or memories this image evokes." Cultural readings you never put in come back to you.
def critique_artwork(image_path: str) -> dict:
"""Get feedback on a piece through three framings."""
framings = {
"gaze_order": "List where the eye goes first, second, and last, with one reason each.",
"tension": "Name two pairs of elements that pull against each other in this frame.",
"association": "Name three places, times, or memories this image evokes.",
}
image_bytes = Path(image_path).read_bytes()
encoded = base64.b64encode(image_bytes).decode()
out = {}
for key, q in framings.items():
resp = model.generate_content([
q, {"mime_type": "image/jpeg", "data": encoded}
])
out[key] = resp.text.strip()
return outWhat matters isn't the answers themselves — it's reading the gaps between them. Where Vision is confident and wrong is often exactly where I've placed intent without noticing. As with Work B mislocating the visual entry point, a misreading can be more eloquent than any production note.
The one thing I'm careful about: don't bend the work toward what Vision prefers. Optimize for the composition an AI calls "well-balanced" and the work drifts quietly toward the average. Use it as a mirror, not a director. That's the one line I keep.
"Seeing" vs. "Reading" — the Question That Stayed With Me
The most interesting part of this experiment wasn't about technical precision.
When AI "sees," it matches visual inputs to existing, verbalized patterns — binding color, texture, and composition to known concepts. When I make work, I'm usually trying to leave something on the screen that doesn't fit existing language. Intuition leads; words follow.
Gemini runs that sequence in reverse: starting from language patterns and working toward the visual. Neither direction is wrong, but the difference itself raises a real question about what "seeing" as a verb means. When its reading doesn't match my intention, a productive question remains — "why did it read it that way?" — and following that question often leads back to something I'd put into the work without fully noticing. Its imperfect readings have quietly become part of my production feedback loop.
Final Verdict
Gemini Vision is excellent at processing volume — not at replacing a maker's judgment.
I'm adding 50–100 new wallpaper images to my app each month. Description writing, category assignment, suitability review — that workflow has compressed to roughly one-third of the time it used to take. That's the real value.
The question "what is it about this piece that moves people?" is still mine to answer. It isn't complete, and that incompleteness is reason enough to keep working with it.
For multimodal API patterns and practical applications, the Gemini Multimodal API Practical Guide is a useful reference. For taking analyzed material into generation, Gemini 3.2 Pro × Imagen 4: 30 Days of Expanding Original Artwork into 120 Wallpaper Variants covers the full pipeline.
I hope this is useful for anyone running both a creative practice and an app business at the same time.