glichPostGen / services /imageService.js
PLUTON\igor.kreyda
Initial commit
66e3a81
/**
* Image Service
* Handles communication with Image Generation APIs.
*/
const axios = require('axios'); // Assuming axios might be used
// Placeholder for API Key configuration
const API_KEY = process.env.IMG_API_KEY || process.env.LLM_API_KEY || '';
const MODEL = 'gemini-3-pro-image-preview';
const API_URL = `https://generativelanguage.googleapis.com/v1beta/models/${MODEL}:generateContent`;
/**
* Generates an image based on the text prompt.
* @param {string} prompt - The text description for the image.
* @param {Object} options - Optional parameters (aspectRatio, etc.)
* @returns {Promise<string>} - The base64 string of the generated image.
*/
async function generateImage(prompt, options = {}) {
if (!API_KEY) {
throw new Error("IMG_API_KEY or LLM_API_KEY is not defined in environment variables.");
}
try {
console.log(`[Image Service] Sending request to ${MODEL}...`, prompt);
const url = `${API_URL}?key=${API_KEY}`;
const payload = {
contents: [{
parts: [{
text: prompt
}]
}]
};
// Add optional configuration if supported by the model and needed
/*
if (options.aspectRatio) {
payload.generationConfig = {
aspectRatio: options.aspectRatio // e.g., "1:1", "4:3", "16:9"
};
}
*/
const response = await axios.post(url, payload, {
headers: {
'Content-Type': 'application/json'
},
timeout: 120000 // 2 minutes timeout
});
// Extract base64 image data from Gemini response structure
if (response.data && response.data.candidates && response.data.candidates.length > 0) {
const candidate = response.data.candidates[0];
if (candidate.content && candidate.content.parts) {
const imagePart = candidate.content.parts.find(p => p.inlineData);
if (imagePart && imagePart.inlineData) {
return imagePart.inlineData.data; // This is the base64 string
}
}
}
console.warn("[Image Service] Unexpected response structure:", JSON.stringify(response.data));
throw new Error("Empty or invalid response from Image Generation API.");
} catch (error) {
console.error('[Image Service] Error generating image:', error.response ? JSON.stringify(error.response.data) : error.message);
throw error;
}
}
/**
* Regenerates/Edits an image based on a text prompt and an existing image.
*
* @param {string} prompt - The text instruction.
* @param {string} imageBase64 - The base64 string of the previous image.
* @returns {Promise<string>} - The base64 string of the new image.
*/
async function regenerateImage(prompt, imageBase64) {
if (!API_KEY) {
throw new Error("IMG_API_KEY or LLM_API_KEY is not defined.");
}
try {
console.log(`[Image Service] Regenerating image with prompt: ${prompt}`);
const url = `${API_URL}?key=${API_KEY}`;
const payload = {
contents: [{
parts: [
{ text: prompt },
{
inline_data: {
mime_type: "image/png", // Assuming PNG for now, simplest for base64
data: imageBase64
}
}
]
}]
};
const response = await axios.post(url, payload, {
headers: { 'Content-Type': 'application/json' },
timeout: 120000
});
if (response.data && response.data.candidates && response.data.candidates.length > 0) {
const candidate = response.data.candidates[0];
if (candidate.content && candidate.content.parts) {
const imagePart = candidate.content.parts.find(p => p.inlineData);
if (imagePart && imagePart.inlineData) {
return imagePart.inlineData.data;
}
}
}
console.warn("[Image Service] Unexpected response structure:", JSON.stringify(response.data));
throw new Error("Empty or invalid response from Image Generation API.");
} catch (error) {
console.error('[Image Service] Error regenerating image:', error.response ? JSON.stringify(error.response.data) : error.message);
throw error;
}
}
module.exports = {
generateImage,
regenerateImage
};