Add reference images from previous page and story characters for consist

This commit is contained in:
Riccardo Giorato
2025-12-26 18:08:21 +01:00
parent 7fd5367577
commit 85f18f0ed1
6 changed files with 278 additions and 219 deletions
+21 -1
View File
@@ -6,6 +6,8 @@ import {
createPage,
getNextPageNumber,
getStoryWithPagesBySlug,
getLastPageImage,
getStoryCharacterImages,
} from "@/lib/db-actions";
import { freeTierRateLimit } from "@/lib/rate-limit";
import { uploadImageToS3 } from "@/lib/s3-upload";
@@ -84,6 +86,24 @@ export async function POST(request: NextRequest) {
const dimensions = FIXED_DIMENSIONS;
// Collect reference images: previous page + story characters + current characters
let referenceImages: string[] = [];
// Get previous page image for style consistency (unless it's page 1)
if (nextPageNumber > 1) {
const lastPageImage = await getLastPageImage(story.id);
if (lastPageImage) {
referenceImages.push(lastPageImage);
}
}
// Get story character images (up to 2 most recent)
const storyCharacterImages = await getStoryCharacterImages(story.id);
referenceImages.push(...storyCharacterImages.slice(-2)); // Take last 2
// Add current character images to references
referenceImages.push(...characterImages);
// Build the prompt with continuation context
const previousPages = pages.map(p => ({
prompt: p.prompt,
@@ -108,7 +128,7 @@ export async function POST(request: NextRequest) {
width: dimensions.width,
height: dimensions.height,
temperature: 0.1,
reference_images: characterImages.length > 0 ? characterImages : undefined,
reference_images: referenceImages.length > 0 ? referenceImages : undefined,
});
} catch (error) {
console.error("Together AI API error:", error);
+22 -3
View File
@@ -7,6 +7,8 @@ import {
createPage,
getNextPageNumber,
getStoryById,
getLastPageImage,
getStoryCharacterImages,
} from "@/lib/db-actions";
import { freeTierRateLimit } from "@/lib/rate-limit";
import { COMIC_STYLES } from "@/lib/constants";
@@ -89,9 +91,11 @@ export async function POST(request: NextRequest) {
let page;
let story;
let referenceImages: string[] = [];
if (storyId) {
const story = await getStoryById(storyId);
// Continuation: get previous page image and story character images
story = await getStoryById(storyId);
if (!story) {
return NextResponse.json({ error: "Story not found" }, { status: 404 });
}
@@ -103,7 +107,20 @@ export async function POST(request: NextRequest) {
prompt,
characterImageUrls: characterImages,
});
// Get previous page image for style consistency (unless it's page 1)
if (nextPageNumber > 1) {
const lastPageImage = await getLastPageImage(storyId);
if (lastPageImage) {
referenceImages.push(lastPageImage);
}
}
// Get story character images (up to 2 most recent)
const storyCharacterImages = await getStoryCharacterImages(storyId);
referenceImages.push(...storyCharacterImages.slice(-2)); // Take last 2
} else {
// New story: no previous page reference
story = await createStory({
title: prompt.length > 50 ? prompt.substring(0, 50) + "..." : prompt,
description: undefined,
@@ -119,6 +136,9 @@ export async function POST(request: NextRequest) {
});
}
// Add current character images to references
referenceImages.push(...characterImages);
const dimensions = FIXED_DIMENSIONS;
const fullPrompt = buildComicPrompt({
@@ -139,8 +159,7 @@ export async function POST(request: NextRequest) {
width: dimensions.width,
height: dimensions.height,
temperature: 0.1, // Lower temperature for more consistent face matching
reference_images:
characterImages.length > 0 ? characterImages : undefined,
reference_images: referenceImages.length > 0 ? referenceImages : undefined,
});
} catch (error) {
console.error("Together AI API error:", error);
+15 -24
View File
@@ -3,8 +3,7 @@
import { Navbar } from "@/components/landing/navbar"
import { Footer } from "@/components/landing/footer"
import { LandingHero } from "@/components/landing/hero-section"
import { StoryInput } from "@/components/landing/story-input"
import { CreateButton } from "@/components/landing/create-button"
import { ComicCreationForm } from "@/components/landing/comic-creation-form"
import { useState, useEffect } from "react"
export default function Home() {
@@ -43,28 +42,20 @@ export default function Home() {
<div className="max-w-xl mx-auto lg:mx-0 w-full z-10">
<LandingHero />
<div className="space-y-4 sm:space-y-5 mt-4 sm:mt-5">
<div className="opacity-0 animate-fade-in-up animation-delay-100">
<StoryInput
prompt={prompt}
setPrompt={setPrompt}
style={style}
setStyle={setStyle}
characterFiles={characterFiles}
setCharacterFiles={setCharacterFiles}
isLoading={isLoading}
/>
</div>
<div className="opacity-0 animate-fade-in-up animation-delay-200">
<CreateButton
prompt={prompt}
style={style}
characterFiles={characterFiles}
isLoading={isLoading}
setIsLoading={setIsLoading}
/>
</div>
</div>
<div className="space-y-4 sm:space-y-5 mt-4 sm:mt-5">
<div className="opacity-0 animate-fade-in-up animation-delay-100">
<ComicCreationForm
prompt={prompt}
setPrompt={setPrompt}
style={style}
setStyle={setStyle}
characterFiles={characterFiles}
setCharacterFiles={setCharacterFiles}
isLoading={isLoading}
setIsLoading={setIsLoading}
/>
</div>
</div>
</div>
</div>