Integrate Stable Diffusion API in Next.js for Image Variations
In the world of digital art and creativity, AI has opened up exciting frontiers. With models like Stable Diffusion, users can transform and generate images based on their inputs. In this guide, we'll integrate the Stable Diffusion API into a Next.js application, allowing users to upload multiple reference images and receive artistic variations based on provided prompts. Here’s how to set it up step by step.
First, we need to set up an API route that can handle multiple image uploads and interface with the Stable Diffusion API. Make sure to have the formidable package installed in your Next.js app to manage file uploads effectively:
npm install formidable
Let’s create a new API route in pages/api/generateImage.js to process incoming requests. This route will accept image uploads, read the files, and send them to the Stable Diffusion API.
Here is how you can implement the API route:
// pages/api/generateImage.js
import formidable from 'formidable';
import fs from 'fs';
import axios from 'axios';
// Allow Next.js to handle form data
export const config = {
api: {
bodyParser: false,
},
};
const handler = async (req, res) => {
if (req.method === 'POST') {
const form = new formidable.IncomingForm();
form.parse(req, async (err, fields, files) => {
if (err) {
return res.status(500).json({ error: 'Failed to parse form data' });
}
const { prompt } = fields;
const imageFiles = Array.isArray(files.image) ? files.image : [files.image];
const imageBufferArray = await Promise.all(imageFiles.map(async (file) => {
const imageBuffer = fs.readFileSync(file.filepath);
return {
buffer: imageBuffer,
filename: file.originalFilename,
contentType: file.mimetype,
};
}));
try {
const formData = new FormData();
imageBufferArray.forEach(file => {
formData.append('images', file.buffer, {
filename: file.filename,
contentType: file.contentType,
});
});
formData.append('prompt', prompt);
// Here you'd call the Stable Diffusion API
// NOTE: You need to replace `YOUR_STABLE_DIFFUSION_API_URL` and `YOUR_API_KEY` with actual values
const response = await axios.post('YOUR_STABLE_DIFFUSION_API_URL', formData, {
headers: {
'Authorization': `Bearer YOUR_API_KEY`, // Use your Stable Diffusion API Key
...formData.getHeaders(),
},
});
const generatedImages = response.data.generated_images; // Adjust according to your API response structure
res.status(200).json({ urls: generatedImages });
} catch (error) {
console.error('Error generating image variation:', error.response ? error.response.data : error.message);
res.status(500).json({ error: 'Failed to generate image' });
}
});
} else {
res.setHeader('Allow', ['POST']);
res.status(405).end(`Method ${req.method} Not Allowed`);
}
};
export default handler;
Now that we have our API ready, let's create a frontend component that allows users to upload their reference images and provide a descriptive prompt. We’ll build a component named GenerateImage.js which includes a file input for multiple selections and a textarea for the user's prompt.
Here’s an example of the GenerateImage component:
// components/GenerateImage.js
import { useState } from 'react';
const GenerateImage = () => {
const [prompt, setPrompt] = useState('');
const [imageFiles, setImageFiles] = useState([]);
const [imageUrls, setImageUrls] = useState([]);
const handleFileChange = (e) => {
setImageFiles(Array.from(e.target.files));
};
const handleSubmit = async (e) => {
e.preventDefault();
const formData = new FormData();
imageFiles.forEach((file) => {
formData.append('image', file);
});
formData.append('prompt', prompt);
const response = await fetch('/api/generateImage', {
method: 'POST',
body: formData,
});
const data = await response.json();
if (response.ok) {
setImageUrls(data.urls); // Assuming the API returns an array of URLs
} else {
console.error(data.error);
}
};
return (
<div>
<form onSubmit={handleSubmit}>
<input
type="file"
accept="image/*"
multiple
onChange={handleFileChange}
required
/>
<textarea
value={prompt}
onChange={(e) => setPrompt(e.target.value)}
placeholder="Describe your image..."
required
/>
<button type="submit">Generate Image</button>
</form>
<div>
{imageUrls.length > 0 && imageUrls.map((url, index) => (
<img key={index} src={url} alt={`Generated ${index}`} />
))}
</div>
</div>
);
};
export default GenerateImage;
Finally, we can incorporate the GenerateImage component into a page, such as pages/index.js, to create an engaging user interface.
Here’s what the index.js page might look like:
// pages/index.js
import GenerateImage from '../components/GenerateImage';
export default function Home() {
return (
<div>
<h1>AI-Powered Image Variation Generator</h1>
<GenerateImage />
</div>
);
}
With this setup, users can upload multiple images and provide a prompt for the type of artistic variation they want. Once the images are uploaded, the Stable Diffusion API processes these inputs and returns a new set of images, showcasing the creative possibilities that AI can bring to digital art.
This system not only embodies the potential of AI in content creation but also empowers users to explore their artistic visions through practical implementation. By seamlessly integrating Stable Diffusion into a user-friendly platform, you take a significant step toward making advanced AI tools accessible to everyone.