DashX / plugins /img2anime.js
HerzaJ's picture
Update plugins/img2anime.js
b1ad9b3 verified
const axios = require('axios');
class AnimeConverter {
constructor() {
this.baseURL = 'https://api.anifun.ai/aitools';
this.tempURL = 'https://temp.anifun.ai';
this.headers = {
'Accept': 'application/json, text/plain, */*',
'Content-Type': 'application/json',
'fp': '3bb76e9ae8e3349d2b18784710f9fcf2',
'fp1': '5J0h1+bPFg4F6qVNO46PpRwyoEoxaViPWymZNXDJBp8Na7vNifH6jre49yHOnzRP',
'x-guide': 'rYJ2cO93MBTiPlC0ipi8WySUJwAa30Kvjigyvz41a6kCR7hopnzY512gBRd8nGkFB7dNAKkf01jW/3LvfyC9e8U5HZtWnDPoql58VJXOm2VSGyEXPmTzWIkG2PhDFhZnbn/nM3hrjh2YI84k2dpT7q8Hq3tLZ1qV2Yegucrs0hI=',
'theme-version': '83EmcUoQTUv50LhNx0VrdcK8rcGexcP35FcZDcpgWsAXEyO4xqL5shCY6sFIWB2Q',
'X-code': Date.now().toString()
};
this.models = {
'meina': 'MeinaHentai_v4.safetensors',
'anime': 'animeModel_v1.safetensors',
'manga': 'mangaStyle_v2.safetensors'
};
}
async uploadImage(imageUrl) {
const imageResponse = await axios.get(imageUrl, {
responseType: 'arraybuffer',
timeout: 45000
});
const FormData = require('form-data');
const formData = new FormData();
formData.append('file', Buffer.from(imageResponse.data), {
filename: 'image.jpg',
contentType: 'image/jpeg'
});
const response = await axios.post(`${this.baseURL}/upload-img`, formData, {
headers: {
...this.headers,
...formData.getHeaders()
},
timeout: 60000
});
if (response.data.code !== 200) {
throw new Error(`Upload failed: ${response.data.message}`);
}
return response.data.data.path;
}
async createTask(imagePath, model) {
const modelName = this.models[model] || this.models['meina'];
const response = await axios.post(`${this.baseURL}/of/create`, {
fn_name: 'demo-photo2anime',
call_type: 3,
input: {
source_image: imagePath,
model: modelName,
request_from: 16
},
data: '',
request_from: 16,
origin_from: '68d425c58e76bc6c'
}, {
headers: {
...this.headers,
'X-code': Date.now().toString()
},
timeout: 30000
});
if (response.data.code !== 200) {
throw new Error(`Task creation failed: ${response.data.message}`);
}
return response.data.data.task_id;
}
async checkStatus(taskId, maxRetries = 60) {
for (let i = 0; i < maxRetries; i++) {
const response = await axios.post(`${this.baseURL}/of/check-status`, {
task_id: taskId,
fn_name: 'demo-photo2anime',
call_type: 3,
request_from: 16,
origin_from: '68d425c58e76bc6c'
}, {
headers: {
...this.headers,
'X-code': Date.now().toString()
},
timeout: 25000
});
if (response.data.code !== 200) {
throw new Error(`Status check failed: ${response.data.message}`);
}
const status = response.data.data.status;
if (status === 2) {
return `${this.tempURL}/${response.data.data.result_image}`;
}
await new Promise(resolve => setTimeout(resolve, 3000));
}
throw new Error('Processing timeout');
}
async convert(imageUrl, model = 'meina') {
const imagePath = await this.uploadImage(imageUrl);
const taskId = await this.createTask(imagePath, model);
const resultUrl = await this.checkStatus(taskId);
return resultUrl;
}
}
const handler = async (req, res) => {
try {
const { image, key, model } = req.query;
if (!image || !key) {
return res.status(400).json({
success: false,
error: 'Missing required parameters: image and key'
});
}
const modelType = model || 'meina';
const validModels = ['meina', 'anime', 'manga'];
if (!validModels.includes(modelType)) {
return res.status(400).json({
success: false,
error: 'Invalid model parameter',
availableModels: validModels
});
}
const converter = new AnimeConverter();
const resultUrl = await converter.convert(image, modelType);
res.json({
author: 'Herza',
success: true,
data: {
model: modelType,
url: resultUrl
}
});
} catch (error) {
res.status(500).json({
success: false,
error: error.message
});
}
};
module.exports = {
name: 'Image to Anime Converter',
description: 'Convert photos to anime style using AI',
type: 'GET',
routes: ['api/AI/img2anime'],
tags: ['ai', 'image', 'anime', 'converter'],
main: ['AI'],
parameters: ['image', 'key'],
enabled: true,
limit: 3,
handler
};