The installation may currently fail. We recommend copying the code below and creating the extension manually in Eidos.
By: Mayne
Transform the image into anime/manga style artwork
export const meta = {
type: "fileAction",
funcName: "convertImageToAnime",
fileAction: {
name: "Convert Image to Anime Style",
description: "Transform the image into anime/manga style artwork",
extensions: [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".webp"]
},
}
export async function convertImageToAnime({ filePath }: { filePath: string }, ctx: Record<string, any>) {
try {
// Check for API key
if (!ctx.env?.OPENROUTER_API_KEY) {
throw new Error("OPENROUTER_API_KEY not found in environment variables. Please set it in script settings.")
}
// Read image file
const imageBuffer = await eidos.currentSpace.fs.readFile(filePath)
// Convert image to base64
const base64Image = btoa(String.fromCharCode(...new Uint8Array(imageBuffer)))
// Get file extension to determine MIME type
const ext = filePath.split('.').pop()?.toLowerCase()
const mimeTypes = {
'jpg': 'image/jpeg',
'jpeg': 'image/jpeg',
'png': 'image/png',
'gif': 'image/gif',
'bmp': 'image/bmp',
'webp': 'image/webp'
}
const mimeType = mimeTypes[ext] || 'image/jpeg'
// Call OpenRouter API to generate anime style image
const response = await fetch('https://openrouter.ai/api/v1/chat/completions', {
method: 'POST',
headers: {
'Authorization': `Bearer ${ctx.env.OPENROUTER_API_KEY}`,
'Content-Type': 'application/json',
'HTTP-Referer': window.location.href,
'X-Title': 'Eidos Anime Converter'
},
body: JSON.stringify({
model: 'google/gemini-3-pro-image-preview',
messages: [
{
role: 'user',
content: [
{
type: 'text',
text: 'Please transform this image into anime/manga style. Convert the image to look like Japanese anime artwork with characteristic anime aesthetics including vibrant colors, stylized features, and anime-style rendering while maintaining the original composition and main elements.'
},
{
type: 'image_url',
image_url: {
url: `data:${mimeType};base64,${base64Image}`
}
}
]
}
],
modalities: ['image', 'text'],
})
})
if (!response.ok) {
throw new Error(`API request failed: ${response.status} ${response.statusText}`)
}
const result = await response.json()
if (result.choices && result.choices[0] && result.choices[0].message) {
const message = result.choices[0].message
if (message.images && message.images.length > 0) {
// Process generated image
const generatedImage = message.images[0]
const imageUrl = generatedImage.image_url.url
// Extract base64 data
const base64Data = imageUrl.split(',')[1]
const imageData = Uint8Array.from(atob(base64Data), c => c.charCodeAt(0))
// Generate new filename
const pathParts = filePath.split('/')
const fileName = pathParts[pathParts.length - 1]
const baseName = fileName.includes('.') ? fileName.split('.').slice(0, -1).join('.') : fileName
const animeFileName = `${baseName}_anime.png`
pathParts[pathParts.length - 1] = animeFileName
const animeFilePath = pathParts.join('/')
// Save generated image
await eidos.currentSpace.fs.writeFile(animeFilePath, imageData)
eidos.currentSpace.notify({
title: "Anime Conversion Complete",
description: `Anime style version generated: "${animeFileName}"`,
})
return {
success: true,
originalFile: filePath,
animeFile: animeFilePath,
message: `Successfully generated anime style version image: ${animeFileName}`
}
} else if (message.content) {
// If no image returned, may have text description
throw new Error(`API returned text instead of image: ${message.content}`)
} else {
throw new Error('No image generated from API')
}
} else {
throw new Error('No result returned from API')
}
} catch (error) {
eidos.currentSpace.notify({
title: "Anime Conversion Failed",
description: `Failed to generate anime version: ${error.message}`,
})
return {
success: false,
error: error.message,
message: `Failed to generate anime version: ${error.message}`
}
}
}