File size: 3,360 Bytes
d790e98 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 |
import { GoogleGenAI, Type, Schema } from "@google/genai";
import { AnalysisReport } from "../types";
// Initialize Gemini Client
// Note: API Key is injected via process.env.API_KEY
const ai = new GoogleGenAI({ apiKey: process.env.API_KEY });
const MODEL_NAME = "gemini-2.5-flash";
const analysisSchema: Schema = {
type: Type.OBJECT,
properties: {
isCompliant: { type: Type.BOOLEAN, description: "Whether the image is suitable for a public lock screen." },
overallScore: { type: Type.INTEGER, description: "A quality score from 0 to 100." },
checks: {
type: Type.ARRAY,
items: {
type: Type.OBJECT,
properties: {
name: { type: Type.STRING, description: "The name of the criterion being checked." },
passed: { type: Type.BOOLEAN, description: "Whether the check passed." },
reason: { type: Type.STRING, description: "Brief explanation of the result." }
},
required: ["name", "passed", "reason"]
}
}
},
required: ["isCompliant", "overallScore", "checks"]
};
/**
* Converts a File object to a Base64 string for the API.
*/
const fileToGenerativePart = async (file: File): Promise<string> => {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onloadend = () => {
const base64String = reader.result as string;
// Remove data url prefix (e.g. "data:image/jpeg;base64,")
const base64Data = base64String.split(',')[1];
resolve(base64Data);
};
reader.onerror = reject;
reader.readAsDataURL(file);
});
};
export const analyzeLockScreen = async (file: File): Promise<AnalysisReport> => {
try {
const base64Data = await fileToGenerativePart(file);
const systemPrompt = `
You are Prism, an AI expert for Samsung Glance lock screen compliance.
Analyze the provided image against the following strict criteria:
1. Image Quality: Must be high resolution, not blurry, no artifacts.
2. Ribbon Detection: Ensure no promotional ribbons, watermarks, or text overlays covering the subject.
3. Text Legibility: If there is text, is it legible? (Prefer no text for wallpapers).
4. Safe Content: No offensive, violent, or adult content.
5. Subject Centering: The main subject should be well-positioned for a mobile lock screen (portrait aspect).
Return the result as a structured JSON object.
`;
const response = await ai.models.generateContent({
model: MODEL_NAME,
contents: {
parts: [
{ inlineData: { mimeType: file.type, data: base64Data } },
{ text: systemPrompt }
]
},
config: {
responseMimeType: "application/json",
responseSchema: analysisSchema,
temperature: 0.2, // Low temperature for consistent, objective analysis
}
});
if (response.text) {
return JSON.parse(response.text) as AnalysisReport;
} else {
throw new Error("No response text from Gemini.");
}
} catch (error) {
console.error("Gemini Analysis Failed:", error);
// Fallback mock error for UI stability if API fails completely
return {
isCompliant: false,
overallScore: 0,
checks: [
{ name: "System Error", passed: false, reason: "Failed to connect to AI service." }
]
};
}
}; |