Reframe Image
The Reframe feature allows you to intelligently reframe images to different aspect ratios using AI-powered cropping and extension. This is powered by the Luma Reframe Image model on Replicate.
Overview
The Reframe API uses the luma/reframe-image model to intelligently adjust images to new aspect ratios. Unlike simple cropping or stretching, this AI-powered approach can:
- Smart Cropping: Identifies important elements in the image and preserves them
- Content-Aware Extension: Can generate new content to fill areas when expanding
- Flexible Positioning: Offers fine control over crop positioning and boundaries
- Multiple Aspect Ratios: Supports common aspect ratios from square to ultra-wide
Basic Usage
Using JSON
import { ImagineoAIClient } from '@imagineoai/javascript';
const client = new ImagineoAIClient(apiUrl, {
apiKey: process.env.IMAGINEOAI_API_KEY
});
// Reframe an image to 16:9 aspect ratio
const result = await client.images.reframe.json({
prompt: "A scenic landscape with mountains",
image_url: "https://example.com/original-image.jpg",
aspect_ratio: "16:9"
});
console.log("Reframe initiated:", result);
// {
// success: true,
// run_id: "abc-123",
// prediction_id: "pred-456",
// status: "processing",
// message: "Image reframing started successfully"
// }
Using FormData
// For file uploads from browser or Node.js
const fileInput = document.getElementById('imageInput');
const file = fileInput.files[0];
const result = await client.images.reframe.formData({
prompt: "Portrait of a person in urban setting",
image_file: file,
aspect_ratio: "9:16" // Vertical for social media
});
Using Previous Run ID
// Reframe an image from a previous generation
const result = await client.images.reframe.json({
prompt: "Beautiful sunset over ocean",
run_id: "previous-run-id-123",
aspect_ratio: "21:9" // Cinematic ultra-wide
});
Aspect Ratios
The following aspect ratios are supported:
| Aspect Ratio | Common Use Cases |
|---|---|
1:1 | Square - Instagram posts, profile pictures |
3:4 | Portrait - Traditional photos, portrait prints |
4:3 | Standard landscape - Old TVs, iPad, presentations |
9:16 | Vertical - Instagram Stories, TikTok, Reels |
16:9 | Widescreen - YouTube, monitors, TV |
9:21 | Ultra-tall - Vertical banners, mobile scrolling content |
21:9 | Ultra-wide - Cinematic, ultra-wide monitors |
Advanced Positioning
For precise control over how the image is reframed, you can specify positioning parameters:
Grid Positioning
Control where your source image appears in the output:
const result = await client.images.reframe.json({
prompt: "Product shot on white background",
image_url: "https://example.com/product.jpg",
aspect_ratio: "1:1",
grid_position_x: 100, // Horizontal position in pixels
grid_position_y: 50 // Vertical position in pixels
});
Crop Boundaries
Define exact crop boundaries for your content:
const result = await client.images.reframe.json({
prompt: "Architectural photography",
image_url: "https://example.com/building.jpg",
aspect_ratio: "16:9",
x_start: 0, // Left boundary
x_end: 1920, // Right boundary
y_start: 0, // Top boundary
y_end: 1080 // Bottom boundary
});
The distance between start and end points determines the resized dimensions of your content within the output frame.
Model Options
You can specify the model used for reframing:
photon-flash-1(default): Faster processing, good qualityphoton-1: Higher quality output, slightly slower processing
// Using the default fast model
const fastResult = await client.images.reframe.json({
prompt: "Nature photography",
image_url: "https://example.com/nature.jpg",
aspect_ratio: "16:9",
model: "photon-flash-1" // Default, faster
});
// Using the higher quality model
const hqResult = await client.images.reframe.json({
prompt: "Professional landscape photography",
image_url: "https://example.com/landscape.jpg",
aspect_ratio: "21:9",
model: "photon-1" // Higher quality, slower
});
Complete Examples
Social Media Optimization
// Convert landscape photo to various social media formats
async function optimizeForSocialMedia(imageUrl) {
const formats = [
{ name: "Instagram Square", ratio: "1:1" },
{ name: "Instagram Story", ratio: "9:16" },
{ name: "Twitter Header", ratio: "3:1" },
{ name: "Facebook Cover", ratio: "16:9" }
];
const results = await Promise.all(
formats.map(format =>
client.images.reframe.json({
prompt: "Social media optimized image",
image_url: imageUrl,
aspect_ratio: format.ratio
})
)
);
return results.map((result, index) => ({
...result,
format: formats[index].name
}));
}
Batch Processing with Files
async function batchReframeImages(files, targetAspectRatio) {
const results = [];
for (const file of files) {
try {
const result = await client.images.reframe.formData({
prompt: `Reframe to ${targetAspectRatio}`,
image_file: file,
aspect_ratio: targetAspectRatio
});
results.push({
filename: file.name,
...result
});
} catch (error) {
console.error(`Failed to reframe ${file.name}:`, error);
results.push({
filename: file.name,
error: error.message
});
}
}
return results;
}
// Usage
const files = Array.from(document.getElementById('multiFileInput').files);
const reframed = await batchReframeImages(files, "16:9");
Smart Cropping with Positioning
async function smartCropPortrait(imageUrl) {
// Crop to portrait with focus on upper portion (for headshots)
const result = await client.images.reframe.json({
prompt: "Professional headshot portrait",
image_url: imageUrl,
aspect_ratio: "3:4",
grid_position_y: 100, // Position 100 pixels from top
y_start: 0,
y_end: 800 // Crop from top to 800 pixels down
});
return result;
}
Response Format
All reframe operations return a response with the following structure:
{
success: boolean;
run_id: string; // Unique ID for this reframe operation
prediction_id: string; // Replicate prediction ID
status: string; // "processing" initially
message: string; // Descriptive status message
}
Checking Status
Since reframing is an asynchronous operation, you can check the status of your reframe operation using the run ID:
// Initial reframe request
const reframeResult = await client.images.reframe.json({
prompt: "Landscape photo",
image_url: "https://example.com/photo.jpg",
aspect_ratio: "21:9"
});
// Check status using the run endpoint
const status = await client.images.getRun(reframeResult.run_id);
if (status.status === 'completed') {
console.log("Reframed image URL:", status.images[0].url);
}
Error Handling
try {
const result = await client.images.reframe.json({
prompt: "Product photo",
image_url: "https://example.com/product.jpg",
aspect_ratio: "1:1"
});
console.log("Reframe started:", result);
} catch (error) {
if (error.message.includes("insufficient credits")) {
console.error("Out of credits for reframing");
} else if (error.message.includes("Invalid aspect ratio")) {
console.error("Unsupported aspect ratio specified");
} else {
console.error("Reframe failed:", error.message);
}
}
Best Practices
- Choose Appropriate Aspect Ratios: Select aspect ratios that match your target platform or use case
- Use Clear Prompts: Describe what's important in the image to preserve during reframing
- Test Positioning: For critical content, use positioning parameters to ensure important elements are preserved
- Handle Async Nature: Reframing is asynchronous - implement proper status checking
- Consider File Sizes: Large images may take longer to process
- Batch Wisely: When processing multiple images, consider rate limiting and credit usage
Technical Notes
- Model: Uses Luma's
reframe-imagemodel via Replicate - Processing: Asynchronous operation with webhook notifications
- Credits: Each reframe operation consumes usage credits
- File Support: Supports common image formats (JPEG, PNG, WebP)
- Resolution: Output resolution depends on input and aspect ratio
- Limitations: Maximum input file size is typically 10MB
API Reference
JSON Method
client.images.reframe.json(input: ReframeRequest): Promise<ReframeResponse>
Parameters:
prompt(string, required): Description of the desired reframed imageimage_url(string, optional): URL of the image to reframerun_id(string, optional): ID of a previous run to use as sourceaspect_ratio(string, optional): Target aspect ratiomodel(string, optional): Model to use - "photon-flash-1" (default, faster) or "photon-1" (higher quality)grid_position_x(number, optional): Horizontal position in pixelsgrid_position_y(number, optional): Vertical position in pixelsx_start(number, optional): Left crop boundary in pixelsx_end(number, optional): Right crop boundary in pixelsy_start(number, optional): Top crop boundary in pixelsy_end(number, optional): Bottom crop boundary in pixels
FormData Method
client.images.reframe.formData(input: ReframeFormDataRequest): Promise<ReframeResponse>
Parameters:
prompt(string, required): Description of the desired reframed imageimage_file(File/Buffer, optional): Image file to reframeimage_url(string, optional): URL or base64 imagerun_id(string, optional): Database run ID- All other parameters same as JSON method