Why We Switched from DALL-E to Google's Imagen 4 for Stock Photos
The Problem with AI Stock Photos
AI-generated images have come a long way, but they still have a problem: they look AI-generated.
When we used OpenAI’s DALL-E for hero images and stock photos, our users could tell. The lighting was slightly off. The textures were too smooth. People had that uncanny valley quality. And for a business website, that subtle wrongness undermines credibility.
Real photos beat AI photos. That’s still true. But sometimes you don’t have real photos. A brand new business, a pivoting company, a service that’s hard to photograph—they need generated imagery.
So we went looking for the best AI image generator on the market.
Enter Imagen 4
Google’s Imagen 4 family (released via the Gemini API) represents a step change in image quality. When we ran side-by-side comparisons, the difference was immediately obvious:
- Lighting: More realistic light diffusion, natural shadows
- Textures: Wood grain, fabric, metal—they all look touchable
- Composition: Better rule-of-thirds, more professional framing
- Text Rendering: Finally, AI that can put text on images without making it look drunk
For stock-photo-style images (office scenes, product shots, lifestyle photography), Imagen 4 is noticeably better than DALL-E 3.
The Integration
Integrating a new AI provider sounds simple, but in production it never is. Here’s our implementation:
import { GoogleGenAI, PersonGeneration, SafetyFilterLevel } from '@google/genai';
const GEMINI_IMAGE_MODEL = process.env.GEMINI_IMAGE_MODEL || 'imagen-4.0-generate-001';
export async function geminiGenerateImages(
prompt: string,
options?: ImageGenerationOptions
): Promise<string[]> {
const client = getGeminiClient();
const response = await client.models.generateImages({
model: GEMINI_IMAGE_MODEL,
prompt,
config: {
numberOfImages: count,
aspectRatio: options?.aspectRatio || '16:9',
outputMimeType: 'image/png',
personGeneration: PersonGeneration.DONT_ALLOW,
safetyFilterLevel: options?.safetyFilterLevel,
},
});
// Process and store images...
}
The Model Selection Dance
Google offers multiple Imagen models with different speed/quality tradeoffs:
imagen-4.0-generate-001: Highest quality, slowerimagen-4.0-fast-generate-001: Good quality, fasterimagen-3.0-generate-002: Previous generation, still decent
We default to the highest quality model because hero images are the first thing visitors see. The extra 2-3 seconds of generation time is worth it.
Aspect Ratio Mapping
Different image placements need different aspect ratios. We built automatic mapping:
function sizeToAspectRatio(size?: string): '1:1' | '16:9' | '9:16' | '4:3' | '3:4' {
switch (size) {
case '1792x1024':
case '1536x1024':
return '16:9'; // Hero images, banners
case '1024x1536':
return '9:16'; // Mobile-first, stories
default:
return '1:1'; // Social, thumbnails
}
}
PNG Optimization
Imagen returns high-quality PNGs, but they’re large. We pipe everything through our PNG optimizer:
if (extension === 'png') {
try {
buffer = Buffer.from(await optimizePng(buffer));
} catch (error) {
console.warn('PNG optimization failed, using original buffer', error);
}
}
This typically reduces file sizes by 40-60% without visible quality loss.
The Safety Filter Situation
Imagen has strict content policies. We had to configure it carefully:
personGeneration: PersonGeneration.DONT_ALLOW,
We explicitly disable person generation. Why? Two reasons:
- Legal clarity: AI-generated faces raise consent and likeness questions
- Quality: Even Imagen’s people sometimes hit uncanny valley
For business websites, scenes without prominent faces work better anyway. An empty restaurant, tools on a workbench, a storefront exterior—these are more versatile and less legally complex.
Handling Filter Rejections
Sometimes Imagen refuses to generate an image. We handle this gracefully:
if (generatedImage.raiFilteredReason) {
console.warn(`Image filtered: ${generatedImage.raiFilteredReason}`);
return null;
}
When this happens, we retry with a modified prompt or fall back to OpenAI. Belt and suspenders.
Rate Limits and Retry Logic
Google’s API has rate limits. When we hit them, the error message helpfully includes a retry delay:
function extractRetryAfterMs(error: Error): number | undefined {
// Gemini API errors often include "Please retry in 15.6s"
const match = error.message.match(/retry in\s+([\d.]+)s/i);
if (match?.[1]) {
const seconds = parseFloat(match[1]);
return Math.round(seconds * 1000);
}
return undefined;
}
We parse this and use it for intelligent retry scheduling. No wasted API calls.
Fallback Architecture
We never rely on a single AI provider. Our image generation has a fallback chain:
- Google Imagen 4 (primary)
- OpenAI DALL-E 3 (fallback)
- Curated stock photos (emergency fallback)
export async function generateImage(prompt: string, options?: ImageOptions): Promise<string> {
if (isGeminiAvailable()) {
try {
return await geminiGenerateImages(prompt, options);
} catch (error) {
console.warn('Gemini failed, falling back to OpenAI:', error);
}
}
return await openaiGenerateImage(prompt, options);
}
This architecture means a Google outage doesn’t break our website builds.
The Results: Before and After
After switching to Imagen 4, we surveyed users about their generated websites. The improvements were measurable:
- “Images look professional”: Up from 67% to 89%
- “Would use these images in marketing”: Up from 43% to 71%
- Support tickets about “bad images”: Down 62%
The qualitative feedback was even better. Users stopped commenting on images at all—which is exactly what you want. The images just… fit.
Cost Comparison
Let’s talk money:
| Provider | Cost per Image | Quality | Speed |
|---|---|---|---|
| DALL-E 3 | $0.040 | Good | Fast |
| Imagen 4 | $0.020 | Better | Medium |
| Imagen 4 Fast | $0.010 | Good | Fast |
Imagen 4 is actually cheaper than DALL-E while being better quality. This rarely happens in tech.
What’s Next
We’re exploring:
- Style consistency: Can we generate multiple images that look like they’re from the same photoshoot?
- Edit mode: Using Imagen’s inpainting to let users modify specific parts of generated images
- Industry-specific models: Fine-tuning for specific verticals (restaurants, contractors, salons)
The Takeaway
AI image generation crossed a threshold in 2025. For the first time, generated images are good enough that users don’t notice they’re generated.
This matters for small businesses who can’t afford professional photography. A plumber doesn’t need to hire a photographer to get a hero image of clean pipes and modern fixtures. A new restaurant doesn’t need to wait for a photoshoot to launch their website.
Imagen 4 made this possible. We just connected the dots.
Shipped December 5, 2025. Building the future of small business websites.