Improve image focus by centering on people and faces
Update AI prompts for more accurate focal point detection and adjust image rendering in various components (MediumCard, SideCard, SingleImageCarousel) to utilize these focal points, enhancing visual composition. Replit-Commit-Author: Agent Replit-Commit-Session-Id: 517dfa7b-26ac-463d-a6e1-a58c6df97188 Replit-Commit-Checkpoint-Type: full_checkpoint Replit-Commit-Event-Id: 4e108b3d-fbcd-43ec-8d2f-0a6ed15b2c47 Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/517dfa7b-26ac-463d-a6e1-a58c6df97188/drGbo1a Replit-Helium-Checkpoint-Created: true
This commit is contained in:
+20
-41
@@ -9,6 +9,17 @@ const openai = new OpenAI({
|
||||
|
||||
const cache = new Map<string, { x: number; y: number }>();
|
||||
|
||||
const SYSTEM_PROMPT = `You are an image analysis tool that detects where faces and people are located in photographs.
|
||||
Analyze the image and find the PRIMARY person or group of people. Report the CENTER of their face(s) as x,y percentages.
|
||||
- x=0 means far left edge, x=100 means far right edge
|
||||
- y=0 means very top edge, y=100 means very bottom edge
|
||||
- For a person's face in the upper third, y should be around 15-35
|
||||
- For a person standing centered, x should be around 40-60
|
||||
- For a group photo, find the center of the group's faces
|
||||
- Be PRECISE, do NOT default to 50,50. Actually look at where faces are.
|
||||
- If there are multiple people, find the most prominent face or group center.
|
||||
Return ONLY a JSON object like {"x":42,"y":28} with no other text.`;
|
||||
|
||||
export async function analyzeFocalPoint(imagePath: string): Promise<{ x: number; y: number }> {
|
||||
const originalPath = imagePath;
|
||||
if (cache.has(originalPath)) {
|
||||
@@ -16,8 +27,7 @@ export async function analyzeFocalPoint(imagePath: string): Promise<{ x: number;
|
||||
}
|
||||
|
||||
try {
|
||||
let imageData: string;
|
||||
let mimeType = "image/webp";
|
||||
let imageContent: { type: "image_url"; image_url: { url: string; detail: "auto" | "low" | "high" } };
|
||||
|
||||
if (imagePath.startsWith("/uploads/")) {
|
||||
const localPath = path.join(process.cwd(), "client/public", imagePath);
|
||||
@@ -25,61 +35,30 @@ export async function analyzeFocalPoint(imagePath: string): Promise<{ x: number;
|
||||
throw new Error(`File not found: ${localPath}`);
|
||||
}
|
||||
const buffer = fs.readFileSync(localPath);
|
||||
imageData = buffer.toString("base64");
|
||||
const imageData = buffer.toString("base64");
|
||||
let mimeType = "image/webp";
|
||||
if (localPath.endsWith(".jpg") || localPath.endsWith(".jpeg")) mimeType = "image/jpeg";
|
||||
else if (localPath.endsWith(".png")) mimeType = "image/png";
|
||||
imageContent = { type: "image_url", image_url: { url: `data:${mimeType};base64,${imageData}`, detail: "auto" } };
|
||||
} else if (imagePath.startsWith("http")) {
|
||||
const response = await openai.chat.completions.create({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: "You analyze images to find the main subject (person's face or group center). Return ONLY a JSON object with x and y as percentages (0-100). x=50 means horizontal center, y=20 means near top. Example: {\"x\":50,\"y\":30}"
|
||||
},
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{ type: "text", text: "Where is the main subject (face/person) in this image? Return only JSON." },
|
||||
{ type: "image_url", image_url: { url: imagePath, detail: "low" } }
|
||||
]
|
||||
}
|
||||
],
|
||||
max_tokens: 50,
|
||||
});
|
||||
const text = response.choices[0]?.message?.content?.trim() || "";
|
||||
const match = text.match(/\{[^}]+\}/);
|
||||
if (match) {
|
||||
const parsed = JSON.parse(match[0]);
|
||||
const point = {
|
||||
x: Math.max(0, Math.min(100, Number(parsed.x) || 50)),
|
||||
y: Math.max(0, Math.min(100, Number(parsed.y) || 30)),
|
||||
};
|
||||
cache.set(originalPath, point);
|
||||
return point;
|
||||
}
|
||||
throw new Error("Could not parse response");
|
||||
imageContent = { type: "image_url", image_url: { url: imagePath, detail: "auto" } };
|
||||
} else {
|
||||
throw new Error(`Unsupported path: ${imagePath}`);
|
||||
}
|
||||
|
||||
const dataUrl = `data:${mimeType};base64,${imageData}`;
|
||||
|
||||
const response = await openai.chat.completions.create({
|
||||
model: "gpt-4o-mini",
|
||||
messages: [
|
||||
{
|
||||
role: "system",
|
||||
content: "You analyze images to find the main subject (person's face or group center). Return ONLY a JSON object with x and y as percentages (0-100) indicating where the main subject/face is located. x=50 means horizontal center, y=20 means near the top. Example: {\"x\":45,\"y\":30}"
|
||||
},
|
||||
{ role: "system", content: SYSTEM_PROMPT },
|
||||
{
|
||||
role: "user",
|
||||
content: [
|
||||
{ type: "text", text: "Where is the main subject (face/person) in this image? Return only JSON with x,y percentages." },
|
||||
{ type: "image_url", image_url: { url: dataUrl, detail: "low" } }
|
||||
{ type: "text", text: "Where exactly are the faces/people in this image? Be precise with coordinates. Return only JSON." },
|
||||
imageContent
|
||||
]
|
||||
}
|
||||
],
|
||||
max_tokens: 50,
|
||||
max_tokens: 60,
|
||||
});
|
||||
|
||||
const text = response.choices[0]?.message?.content?.trim() || "";
|
||||
|
||||
Reference in New Issue
Block a user