Sets up the foundational project structure, including: - Vite for build tooling. - React for the UI. - Tailwind CSS for styling. - MediaPipe for face tracking capabilities. - Gemini API integration for avatar generation. - Basic configuration files (package.json, vite.config.ts, tsconfig.json). - Initial README with local run instructions. - Core types and a basic Gemini service for image generation.
54 lines
1.7 KiB
TypeScript
54 lines
1.7 KiB
TypeScript
import { GoogleGenAI } from "@google/genai";
|
|
|
|
/**
|
|
* Generates a VTuber avatar image based on user description.
|
|
* Uses gemini-3-pro-image-preview for high quality.
|
|
*/
|
|
export const generateAvatarImage = async (description: string): Promise<string> => {
|
|
try {
|
|
// Initialize client inside the function to ensure we use the most up-to-date API key
|
|
// after the user has completed the selection flow.
|
|
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
|
|
|
|
// We construct a prompt that encourages a good format for a 2D avatar (front facing, clean background)
|
|
const prompt = `
|
|
Create a high-quality, flat 2D anime or stylized character illustration suitable for a VTuber avatar.
|
|
The character should be facing forward (front view).
|
|
The background should be a solid, single color (white or bright green) to allow for easy removal or masking.
|
|
|
|
Character Description: ${description}
|
|
|
|
Style: Vibrant, clean lines, detailed eyes.
|
|
Focus: Head and shoulders only.
|
|
`;
|
|
|
|
const response = await ai.models.generateContent({
|
|
model: 'gemini-3-pro-image-preview',
|
|
contents: {
|
|
parts: [
|
|
{ text: prompt }
|
|
]
|
|
},
|
|
config: {
|
|
imageConfig: {
|
|
aspectRatio: "1:1",
|
|
imageSize: "1K"
|
|
}
|
|
}
|
|
});
|
|
|
|
// Parse response for image data
|
|
for (const part of response.candidates[0].content.parts) {
|
|
if (part.inlineData) {
|
|
const base64EncodeString = part.inlineData.data;
|
|
return `data:image/png;base64,${base64EncodeString}`;
|
|
}
|
|
}
|
|
|
|
throw new Error("No image data found in response");
|
|
} catch (error) {
|
|
console.error("Error generating avatar:", error);
|
|
throw error;
|
|
}
|
|
};
|