studio-lumiere-cli 0.1.6 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +31 -502
- package/dist/cli.js +56 -2
- package/dist/cli.js.map +1 -1
- package/dist/config/options.d.ts +1 -1
- package/dist/config/options.js +1 -1
- package/dist/config/options.js.map +1 -1
- package/dist/image/annotate.js +1 -1
- package/dist/image/annotate.js.map +1 -1
- package/dist/image/beforeAfter.d.ts +2 -0
- package/dist/image/beforeAfter.js +234 -0
- package/dist/image/beforeAfter.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/pipelines/generateImages.js +30 -27
- package/dist/pipelines/generateImages.js.map +1 -1
- package/dist/pipelines/resolve.d.ts +2 -1
- package/dist/pipelines/resolve.js +12 -2
- package/dist/pipelines/resolve.js.map +1 -1
- package/dist/studio/constants/backgrounds.d.ts +1 -0
- package/dist/studio/constants/backgrounds.js +2 -0
- package/dist/studio/constants/backgrounds.js.map +1 -0
- package/dist/studio/constants.d.ts +63 -15
- package/dist/studio/constants.js +512 -166
- package/dist/studio/constants.js.map +1 -1
- package/dist/studio/promptBuilder.d.ts +7 -3
- package/dist/studio/promptBuilder.js +401 -200
- package/dist/studio/promptBuilder.js.map +1 -1
- package/dist/studio/types.d.ts +47 -0
- package/dist/types.d.ts +17 -0
- package/package.json +30 -33
- package/scripts/sync-studio.mjs +16 -16
- package/dist/prompt/buildPrompt.d.ts +0 -4
- package/dist/prompt/buildPrompt.js +0 -322
- package/dist/prompt/buildPrompt.js.map +0 -1
|
@@ -1,21 +1,164 @@
|
|
|
1
|
-
import { ETHNICITY_REGIONS, getRandomBackgroundValue, getRandomBackgroundTreatment, getRandomBlazerValue } from './constants.js';
|
|
2
|
-
export const buildLLMPrompt = (template, detail, secondaryDetail, tertiaryDetail, quaternaryDetail, ethnicity, skinTone, hairColor, background, backgroundType, vibe, imageCount, occasion, styleHint,
|
|
1
|
+
import { ETHNICITY_REGIONS, getRandomBackgroundValue, getRandomBackgroundTreatment, getRandomBlazerValue, JEWELRY_MACRO_QUALITY_PROMPT, JEWELRY_MACRO_QUALITY_PROMPT_2 } from './constants.js';
|
|
2
|
+
export const buildLLMPrompt = (template, detail, secondaryDetail, tertiaryDetail, quaternaryDetail, quinaryDetail, ethnicity, skinTone, hairColor, background, backgroundType, vibe, photographyStyle, imageCount, occasion, backgroundReference, styleHint, uploadMode = 'stacking', editorialMuseCloseUp, editorialMuseUltraCloseUp, flatlayCloseUp, flatlayUltraCloseUp, jewelerInsight, campaignStyle, guidelineReferences, hasMuseReferences = false) => {
|
|
3
3
|
const needsBothHands = template.id === 'hand_model' && imageCount >= 3;
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
4
|
+
const isEditorialMuse = template.id === 'half_body_muse';
|
|
5
|
+
const useEditorialCloseUp = isEditorialMuse && !!editorialMuseCloseUp;
|
|
6
|
+
const useEditorialUltraCloseUp = isEditorialMuse && !!editorialMuseUltraCloseUp;
|
|
7
|
+
const useFlatlayCloseUp = template.id === 'flatlay_creative' && !!flatlayCloseUp;
|
|
8
|
+
const useFlatlayUltraCloseUp = template.id === 'flatlay_creative' && !!flatlayUltraCloseUp;
|
|
9
|
+
let quantityConstraint = '';
|
|
10
|
+
if (uploadMode === 'multi_angle') {
|
|
11
|
+
if (template.hasModel) {
|
|
12
|
+
quantityConstraint = 'The attached image(s) show the EXACT SAME single piece of jewelry (from different angles/perspectives). The model is wearing ONLY this single piece. Render EXACTLY ONE physical instance of that piece. Do NOT duplicate, pair, stack, mirror, or show multiple copies. Do NOT show multiple angles of the piece within the same image. Synthesize the views into a single coherent piece and choose ONE viewpoint for the output.';
|
|
13
|
+
}
|
|
14
|
+
else {
|
|
15
|
+
quantityConstraint = 'The attached image(s) show the EXACT SAME single piece of jewelry (from different angles/perspectives). Render EXACTLY ONE physical instance of that piece. Do NOT duplicate, pair, stack, mirror, or show multiple copies. Do NOT show multiple angles of the piece within the same image. Synthesize the views into a single coherent piece and choose ONE viewpoint for the output.';
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
else if (uploadMode === 'multi_item_single') {
|
|
19
|
+
if (template.hasModel) {
|
|
20
|
+
quantityConstraint = `The attached image shows MULTIPLE distinct jewelry pieces in a single photo. The model is wearing ALL visible pieces together. Each distinct piece must appear EXACTLY ONCE. Do NOT duplicate, mirror, or multiply any piece. Do NOT add any other jewelry.${needsBothHands ? ' IMPORTANT: Show BOTH hands with the pieces distributed naturally and elegantly across both hands -- do NOT cram all pieces onto a single hand.' : ''}`;
|
|
21
|
+
}
|
|
22
|
+
else {
|
|
23
|
+
quantityConstraint = 'The attached image shows MULTIPLE distinct jewelry pieces in a single photo. Include ALL visible pieces together in the final image. Each distinct piece must appear EXACTLY ONCE. Do NOT duplicate, mirror, or multiply them. Do NOT add any other pieces.';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
else if (imageCount > 1) {
|
|
27
|
+
if (template.hasModel) {
|
|
28
|
+
quantityConstraint = `The model is wearing ALL the provided pieces together. Each distinct piece must appear EXACTLY ONCE. Do NOT duplicate, mirror, or multiply any piece. Do NOT add any other jewelry.${needsBothHands ? ' IMPORTANT: Show BOTH hands with the pieces distributed naturally and elegantly across both hands � do NOT cram all pieces onto a single hand.' : ''}`;
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
quantityConstraint = 'The attached image(s) show the EXACT SAME single piece of jewelry (potentially from different angles/perspectives). Render ONLY this single piece in the scene. Synthesize the view(s) to accurately recreate its details. Do NOT generate multiple pieces of jewelry.';
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
else {
|
|
35
|
+
if (template.hasModel) {
|
|
36
|
+
quantityConstraint = 'The model is wearing ONLY the single piece of jewelry shown in the reference. Do NOT add matching earrings, necklaces, or other rings.';
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
quantityConstraint = 'The scene includes ONLY the single piece of jewelry shown in the reference. Do NOT add matching earrings, necklaces, or other rings.';
|
|
40
|
+
}
|
|
41
|
+
}
|
|
7
42
|
// Dynamic Base Concept
|
|
8
43
|
let ethnicityLabel = (ethnicity && ethnicity.id !== 'none') ? ethnicity.name : "professional female";
|
|
44
|
+
const extraModelNotes = [];
|
|
45
|
+
const framingNotes = [];
|
|
46
|
+
if (isEditorialMuse) {
|
|
47
|
+
if (useEditorialUltraCloseUp) {
|
|
48
|
+
framingNotes.push('Framing: extreme close-up crop with jewelry dominating the frame and filling most of the image. Push the camera much closer. It is acceptable to crop out most of the face, head, and torso to prioritize the jewelry. Background and decor may be minimal or out of frame.');
|
|
49
|
+
}
|
|
50
|
+
else if (useEditorialCloseUp) {
|
|
51
|
+
framingNotes.push('Framing: tight close-up with jewelry prominent and larger in frame. It is acceptable to crop out parts of the face, head, and torso to prioritize the jewelry. Background and decor may be minimal or out of frame.');
|
|
52
|
+
}
|
|
53
|
+
else {
|
|
54
|
+
framingNotes.push('Framing: waist-up portrait with face, head, and shoulders visible. Hands may appear but must not be the primary subject. Do NOT crop to hands only.');
|
|
55
|
+
}
|
|
56
|
+
extraModelNotes.push('High-fashion beauty, not girl-next-door; unconventional, memorable, magazine-cover presence.');
|
|
57
|
+
}
|
|
58
|
+
if (isEditorialMuse && ethnicity?.id === 'african') {
|
|
59
|
+
ethnicityLabel = 'Black American (modern, cosmopolitan)';
|
|
60
|
+
extraModelNotes.push('Aesthetic: modern Black American editorial; cosmopolitan, upscale, contemporary.');
|
|
61
|
+
extraModelNotes.push('Avoid traditional/tribal styling, costumes, or regional stereotypes.');
|
|
62
|
+
}
|
|
9
63
|
// Diversity Injection: Pick a specific region if available
|
|
10
|
-
if (ethnicity && ethnicity.id && ETHNICITY_REGIONS[ethnicity.id]) {
|
|
64
|
+
if (ethnicity && ethnicity.id && ETHNICITY_REGIONS[ethnicity.id] && !(isEditorialMuse && ethnicity.id === 'african')) {
|
|
11
65
|
const regions = ETHNICITY_REGIONS[ethnicity.id];
|
|
12
66
|
const randomRegion = regions[Math.floor(Math.random() * regions.length)];
|
|
13
67
|
ethnicityLabel = `${randomRegion} (${ethnicity.name})`;
|
|
14
68
|
}
|
|
15
69
|
let basePrompt = template.basePrompt;
|
|
70
|
+
if (useEditorialUltraCloseUp) {
|
|
71
|
+
basePrompt = 'An extreme close-up editorial photograph of a [ETHNICITY] female model wearing the specific jewelry piece(s) shown. Jewelry should dominate the frame and fill most of the image. It is acceptable to crop out most of the face, head, and torso to prioritize the jewelry. High-fashion editorial mood, beauty-grade skin refinement with smooth even tone, reduced pores, minimal blemishes, still realistic (no plastic skin), cinematic lighting, shot on film.';
|
|
72
|
+
}
|
|
73
|
+
else if (useEditorialCloseUp) {
|
|
74
|
+
basePrompt = 'A tight close-up editorial photograph of a [ETHNICITY] female model wearing the specific jewelry piece(s) shown. Jewelry should be visually dominant. It is acceptable to crop the face, head, or torso to prioritize the jewelry. High-fashion editorial mood, beauty-grade skin refinement with smooth even tone, reduced pores, minimal blemishes, still realistic (no plastic skin), cinematic lighting, shot on film.';
|
|
75
|
+
}
|
|
16
76
|
basePrompt = basePrompt.replace(/\[ETHNICITY\]/g, ethnicityLabel);
|
|
17
77
|
const hairColorLabel = (hairColor && hairColor.id !== 'none') ? hairColor.name.toLowerCase() : "natural colored";
|
|
18
78
|
basePrompt = basePrompt.replace(/\[HAIR_COLOR\]/g, hairColorLabel);
|
|
79
|
+
const sceneDetails = [];
|
|
80
|
+
const modelDetails = [];
|
|
81
|
+
if (!template.hasModel) {
|
|
82
|
+
if (useFlatlayUltraCloseUp) {
|
|
83
|
+
sceneDetails.push('Framing: extreme close-up crop with the jewelry dominating the frame and filling most of the image; push the camera much closer; minimize negative space and background; allow props/material edges to be cropped; emphasize jewelry scale and detail.');
|
|
84
|
+
}
|
|
85
|
+
else if (useFlatlayCloseUp) {
|
|
86
|
+
sceneDetails.push('Framing: tight close-up crop with jewelry filling more of the frame; minimize background and allow props/material edges to be partially cropped; emphasize jewelry scale.');
|
|
87
|
+
}
|
|
88
|
+
if (detail && template.customizationLabel) {
|
|
89
|
+
const detailValue = detail.value.replace(/\[HAIR_COLOR\]/g, hairColorLabel);
|
|
90
|
+
sceneDetails.push(`${template.customizationLabel}: ${detailValue}`);
|
|
91
|
+
}
|
|
92
|
+
if (secondaryDetail && template.secondaryCustomizationLabel) {
|
|
93
|
+
sceneDetails.push(`${template.secondaryCustomizationLabel}: ${secondaryDetail.value}`);
|
|
94
|
+
}
|
|
95
|
+
if (tertiaryDetail && template.tertiaryCustomizationLabel) {
|
|
96
|
+
sceneDetails.push(`${template.tertiaryCustomizationLabel}: ${tertiaryDetail.value}`);
|
|
97
|
+
}
|
|
98
|
+
if (quaternaryDetail && template.quaternaryCustomizationLabel) {
|
|
99
|
+
sceneDetails.push(`${template.quaternaryCustomizationLabel}: ${quaternaryDetail.value}`);
|
|
100
|
+
}
|
|
101
|
+
if (quinaryDetail && template.quinaryCustomizationLabel) {
|
|
102
|
+
sceneDetails.push(`${template.quinaryCustomizationLabel}: ${quinaryDetail.value}`);
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
else {
|
|
106
|
+
if (ethnicity && ethnicity.id !== 'none') {
|
|
107
|
+
modelDetails.push(`Model Ethnicity: ${ethnicityLabel}`);
|
|
108
|
+
}
|
|
109
|
+
if (detail) {
|
|
110
|
+
let detailValue = detail.value.replace(/\[HAIR_COLOR\]/g, hairColorLabel);
|
|
111
|
+
if (detail.id === 'outfit_blazer') {
|
|
112
|
+
detailValue = getRandomBlazerValue();
|
|
113
|
+
}
|
|
114
|
+
if (occasion && template.id === 'half_body_muse') {
|
|
115
|
+
detailValue = `${detailValue}. Adapt any outfit to the selected occasion while preserving the original silhouette and styling direction.`;
|
|
116
|
+
}
|
|
117
|
+
modelDetails.push(`${template.customizationLabel}: ${detailValue}`);
|
|
118
|
+
}
|
|
119
|
+
else if (template.customizationLabel?.toLowerCase().includes('makeup')) {
|
|
120
|
+
modelDetails.push(`${template.customizationLabel}: completely bare faced, no makeup, fresh natural skin`);
|
|
121
|
+
}
|
|
122
|
+
else if (template.customizationLabel?.toLowerCase().includes('nail')) {
|
|
123
|
+
modelDetails.push(`${template.customizationLabel}: natural unpainted nails with a clear healthy coat`);
|
|
124
|
+
}
|
|
125
|
+
if (secondaryDetail) {
|
|
126
|
+
modelDetails.push(`${template.secondaryCustomizationLabel}: ${secondaryDetail.value}`);
|
|
127
|
+
}
|
|
128
|
+
else if (template.secondaryCustomizationLabel?.toLowerCase().includes('makeup')) {
|
|
129
|
+
modelDetails.push(`${template.secondaryCustomizationLabel}: completely bare faced, no makeup, fresh natural skin`);
|
|
130
|
+
}
|
|
131
|
+
else if (template.secondaryCustomizationLabel?.toLowerCase().includes('nail')) {
|
|
132
|
+
modelDetails.push(`${template.secondaryCustomizationLabel}: natural unpainted nails with a clear healthy coat`);
|
|
133
|
+
}
|
|
134
|
+
if (tertiaryDetail) {
|
|
135
|
+
modelDetails.push(`${template.tertiaryCustomizationLabel}: ${tertiaryDetail.value}`);
|
|
136
|
+
}
|
|
137
|
+
else if (template.tertiaryCustomizationLabel?.toLowerCase().includes('makeup')) {
|
|
138
|
+
modelDetails.push(`${template.tertiaryCustomizationLabel}: completely bare faced, no makeup, fresh natural skin`);
|
|
139
|
+
}
|
|
140
|
+
else if (template.tertiaryCustomizationLabel?.toLowerCase().includes('nail')) {
|
|
141
|
+
modelDetails.push(`${template.tertiaryCustomizationLabel}: natural unpainted nails with a clear healthy coat`);
|
|
142
|
+
}
|
|
143
|
+
if (quaternaryDetail) {
|
|
144
|
+
modelDetails.push(`${template.quaternaryCustomizationLabel}: ${quaternaryDetail.value}`);
|
|
145
|
+
}
|
|
146
|
+
if (quinaryDetail) {
|
|
147
|
+
modelDetails.push(`${template.quinaryCustomizationLabel}: ${quinaryDetail.value}`);
|
|
148
|
+
}
|
|
149
|
+
if (skinTone && skinTone.id !== 'none' && !['flatlay_creative', 'floating_minimal', 'museum_exhibit', 'romantic_mood'].includes(template.id)) {
|
|
150
|
+
modelDetails.push(`Model Skin Tone: ${skinTone.value}`);
|
|
151
|
+
}
|
|
152
|
+
if (hairColor && hairColor.id !== 'none' && !['hand_model', 'flatlay_creative', 'floating_minimal', 'romantic_mood'].includes(template.id)) {
|
|
153
|
+
modelDetails.push(`Model Hair Color: ${hairColor.value}`);
|
|
154
|
+
}
|
|
155
|
+
if (extraModelNotes.length > 0) {
|
|
156
|
+
modelDetails.push(...extraModelNotes);
|
|
157
|
+
}
|
|
158
|
+
if (framingNotes.length > 0) {
|
|
159
|
+
modelDetails.push(...framingNotes);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
19
162
|
const CAMERAS = [
|
|
20
163
|
'Hasselblad X2D 100C, 120mm Macro lens, f/2.8',
|
|
21
164
|
'Fujifilm GFX 100II, 110mm f/2 lens',
|
|
@@ -31,146 +174,163 @@ export const buildLLMPrompt = (template, detail, secondaryDetail, tertiaryDetail
|
|
|
31
174
|
'Ilford HP5 (if black and white)'
|
|
32
175
|
];
|
|
33
176
|
const randomFilm = FILM_STOCKS[Math.floor(Math.random() * FILM_STOCKS.length)];
|
|
34
|
-
let instruction =
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
══════════════════════════════════
|
|
40
|
-
Base Concept: ${basePrompt}
|
|
41
|
-
Camera: ${randomCamera}
|
|
42
|
-
Film Stock: ${randomFilm}
|
|
43
|
-
Target: Authentic, high-end editorial photography. Cinematic, naturalistic, slightly imperfect.
|
|
44
|
-
|
|
45
|
-
══════════════════════════════════
|
|
46
|
-
💎 SUBJECT & JEWELRY (HIGHEST PRIORITY)
|
|
47
|
-
══════════════════════════════════
|
|
48
|
-
${quantityConstraint}
|
|
49
|
-
The jewelry matches the reference images EXACTLY in all details: metal type, stone cuts, chain style, settings, etc.
|
|
50
|
-
No additional jewelry pieces or embellishments.
|
|
51
|
-
No sparkles, glitter, or magical glow effects.
|
|
52
|
-
` : `Write a highly detailed, structured photorealistic prompt for the specific jewelry shown in the attached images.
|
|
177
|
+
let instruction = 'A highly detailed, photorealistic photograph featuring the specific jewelry shown in the attached reference image(s).';
|
|
178
|
+
instruction += `
|
|
179
|
+
${JEWELRY_MACRO_QUALITY_PROMPT}
|
|
180
|
+
`;
|
|
181
|
+
instruction += `
|
|
53
182
|
|
|
54
|
-
|
|
183
|
+
----------------------------------
|
|
55
184
|
📸 PHOTOGRAPHY SPECIFICATION
|
|
56
|
-
|
|
57
|
-
Base Concept: ${basePrompt}
|
|
58
|
-
Camera: ${randomCamera}
|
|
59
|
-
Film Stock: ${randomFilm}
|
|
60
|
-
Target: Authentic, high-end editorial photography. Cinematic,
|
|
185
|
+
----------------------------------
|
|
186
|
+
- Base Concept: ${basePrompt}
|
|
187
|
+
- Camera: ${randomCamera}
|
|
188
|
+
- Film Stock: ${randomFilm}
|
|
189
|
+
- Target: Authentic, high-end editorial photography. Cinematic, refined, naturalistic.
|
|
61
190
|
|
|
62
|
-
|
|
191
|
+
----------------------------------
|
|
63
192
|
💎 SUBJECT & JEWELRY (HIGHEST PRIORITY)
|
|
64
|
-
|
|
65
|
-
${quantityConstraint}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
193
|
+
----------------------------------
|
|
194
|
+
- ${quantityConstraint}
|
|
195
|
+
- The jewelry matches the reference images EXACTLY in all details: metal type, stone cuts, chain style, settings, colors, etc.
|
|
196
|
+
- The jewelry MUST be razor-sharp and micro-detailed (tack-sharp edges, crisp facets, ultra-clear metal and stone texture).
|
|
197
|
+
- If the reference image is blurry or low quality, reconstruct the jewelry at higher fidelity; do NOT inherit blur.
|
|
198
|
+
- Absolutely NO blur, soft focus, motion blur, or depth-of-field blur on the jewelry itself (background can be soft).
|
|
199
|
+
- No additional jewelry pieces or embellishments.
|
|
200
|
+
- No sparkles, glitter, or magical glow effects.
|
|
69
201
|
`;
|
|
70
|
-
|
|
71
|
-
if (occasion?.promptDetails) {
|
|
202
|
+
if (jewelerInsight) {
|
|
72
203
|
instruction += `
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
🏛️ SETTING & ENVIRONMENT:
|
|
79
|
-
${occasion.promptDetails.setting}
|
|
204
|
+
----------------------------------
|
|
205
|
+
🔍 JEWELER INSIGHT
|
|
206
|
+
----------------------------------
|
|
207
|
+
Pay special attention to the brand specific details, if any are provided.
|
|
80
208
|
|
|
81
|
-
|
|
82
|
-
${occasion.promptDetails.atmosphere}
|
|
83
|
-
|
|
84
|
-
🎨 COLOR PALETTE:
|
|
85
|
-
${occasion.promptDetails.colorPalette}
|
|
86
|
-
|
|
87
|
-
🌟 CULTURAL & THEMATIC ELEMENTS:
|
|
88
|
-
${occasion.promptDetails.culturalElements}
|
|
89
|
-
|
|
90
|
-
💄 MODEL STYLING & AESTHETIC:
|
|
91
|
-
${occasion.promptDetails.styling}
|
|
209
|
+
${jewelerInsight}
|
|
92
210
|
`;
|
|
93
211
|
}
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
detailValue = getRandomBlazerValue();
|
|
105
|
-
}
|
|
106
|
-
modelDetails.push(`${template.customizationLabel}: ${detailValue}`);
|
|
107
|
-
}
|
|
108
|
-
else if (template.customizationLabel?.toLowerCase().includes('makeup')) {
|
|
109
|
-
modelDetails.push(`${template.customizationLabel}: completely bare faced, no makeup, fresh natural skin`);
|
|
110
|
-
}
|
|
111
|
-
else if (template.customizationLabel?.toLowerCase().includes('nail')) {
|
|
112
|
-
modelDetails.push(`${template.customizationLabel}: natural unpainted nails with a clear healthy coat`);
|
|
113
|
-
}
|
|
114
|
-
if (secondaryDetail) {
|
|
115
|
-
modelDetails.push(`${template.secondaryCustomizationLabel}: ${secondaryDetail.value}`);
|
|
116
|
-
}
|
|
117
|
-
else if (template.secondaryCustomizationLabel?.toLowerCase().includes('makeup')) {
|
|
118
|
-
modelDetails.push(`${template.secondaryCustomizationLabel}: completely bare faced, no makeup, fresh natural skin`);
|
|
119
|
-
}
|
|
120
|
-
else if (template.secondaryCustomizationLabel?.toLowerCase().includes('nail')) {
|
|
121
|
-
modelDetails.push(`${template.secondaryCustomizationLabel}: natural unpainted nails with a clear healthy coat`);
|
|
122
|
-
}
|
|
123
|
-
if (tertiaryDetail) {
|
|
124
|
-
modelDetails.push(`${template.tertiaryCustomizationLabel}: ${tertiaryDetail.value}`);
|
|
125
|
-
}
|
|
126
|
-
else if (template.tertiaryCustomizationLabel?.toLowerCase().includes('makeup')) {
|
|
127
|
-
modelDetails.push(`${template.tertiaryCustomizationLabel}: completely bare faced, no makeup, fresh natural skin`);
|
|
128
|
-
}
|
|
129
|
-
else if (template.tertiaryCustomizationLabel?.toLowerCase().includes('nail')) {
|
|
130
|
-
modelDetails.push(`${template.tertiaryCustomizationLabel}: natural unpainted nails with a clear healthy coat`);
|
|
131
|
-
}
|
|
132
|
-
if (quaternaryDetail) {
|
|
133
|
-
modelDetails.push(`${template.quaternaryCustomizationLabel}: ${quaternaryDetail.value}`);
|
|
134
|
-
}
|
|
135
|
-
if (skinTone && skinTone.id !== 'none' && !template.id.includes('flatlay')) {
|
|
136
|
-
modelDetails.push(`Model Skin Tone: ${skinTone.value}`);
|
|
212
|
+
if (campaignStyle) {
|
|
213
|
+
instruction += `
|
|
214
|
+
----------------------------------
|
|
215
|
+
💫 CAMPAIGN MODE (PREMIUM)
|
|
216
|
+
----------------------------------
|
|
217
|
+
- Campaign Direction: ${campaignStyle.name}
|
|
218
|
+
- ${campaignStyle.prompt}
|
|
219
|
+
- Goal: billboard-level impact. Bold, cinematic, unforgettable.
|
|
220
|
+
- Do NOT override user selections (background, vibe, styling). Amplify them.
|
|
221
|
+
`;
|
|
137
222
|
}
|
|
138
|
-
|
|
139
|
-
|
|
223
|
+
const occasionCultural = occasion?.promptDetails?.culturalElements?.length
|
|
224
|
+
? occasion.promptDetails.culturalElements[Math.floor(Math.random() * occasion.promptDetails.culturalElements.length)]
|
|
225
|
+
: null;
|
|
226
|
+
const occasionDecor = occasion?.promptDetails?.decor?.length
|
|
227
|
+
? occasion.promptDetails.decor[Math.floor(Math.random() * occasion.promptDetails.decor.length)]
|
|
228
|
+
: null;
|
|
229
|
+
if (occasion?.promptDetails) {
|
|
230
|
+
instruction += `
|
|
231
|
+
----------------------------------
|
|
232
|
+
🎭 OCCASION CONTEXT: ${occasion.name.toUpperCase()}
|
|
233
|
+
----------------------------------
|
|
234
|
+
- ${occasion.description}
|
|
235
|
+
- 🌟 CULTURAL & THEMATIC ELEMENTS: ${occasionCultural}
|
|
236
|
+
${occasionDecor ? `- OCCASION DECOR: ${occasionDecor}` : ''}
|
|
237
|
+
`;
|
|
140
238
|
}
|
|
141
239
|
if (modelDetails.length > 0) {
|
|
142
240
|
instruction += `
|
|
143
|
-
|
|
241
|
+
----------------------------------
|
|
144
242
|
👤 MODEL SPECIFICATIONS
|
|
145
|
-
|
|
146
|
-
${modelDetails.join('\n')}
|
|
147
|
-
The model should look like a natural, real human.
|
|
243
|
+
----------------------------------
|
|
244
|
+
${modelDetails.map(detailLine => `- ${detailLine}`).join('\n')}
|
|
245
|
+
- The model should look like a natural, real human.
|
|
148
246
|
`;
|
|
149
247
|
}
|
|
150
|
-
|
|
151
|
-
|
|
248
|
+
if (guidelineReferences && guidelineReferences.length > 0) {
|
|
249
|
+
const guidelineLines = guidelineReferences.map((ref, index) => `- Guideline Reference #${index + 1} = "${ref.name}"`).join('\n');
|
|
152
250
|
instruction += `
|
|
153
|
-
|
|
251
|
+
----------------------------------
|
|
252
|
+
📌 GUIDELINE REFERENCES
|
|
253
|
+
----------------------------------
|
|
254
|
+
- These appear immediately AFTER the ${imageCount} jewelry reference image(s), and BEFORE any background reference image.
|
|
255
|
+
${guidelineLines}
|
|
256
|
+
- When a guideline includes [[ref:Name]], use the matching Guideline Reference image above.
|
|
257
|
+
- Use these ONLY when referenced in the user's guidelines.
|
|
258
|
+
- Treat them as style/lighting/pose/composition cues; do NOT alter jewelry design from the reference.
|
|
259
|
+
`;
|
|
260
|
+
}
|
|
261
|
+
const isSolidBg = !!(background && background.value && background.value.includes('[SOLID_BG]'));
|
|
262
|
+
const hasSettingContext = !!(background || backgroundType || vibe || photographyStyle || backgroundReference);
|
|
263
|
+
const shouldRenderSettingBlock = hasSettingContext || sceneDetails.length > 0;
|
|
264
|
+
if (shouldRenderSettingBlock) {
|
|
265
|
+
const allowCampaignAccent = !(background && background.value && background.value.includes('[USER_BRAND_COLOR]'));
|
|
266
|
+
instruction += `
|
|
267
|
+
----------------------------------
|
|
154
268
|
🎬 SETTING & ENVIRONMENT
|
|
155
|
-
|
|
269
|
+
----------------------------------
|
|
156
270
|
`;
|
|
157
|
-
if (
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
271
|
+
if (isSolidBg) {
|
|
272
|
+
// Extract just the color specification
|
|
273
|
+
const colorValue = background.value.replace('[USER_BRAND_COLOR]', '').replace('[SOLID_BG]', '').trim();
|
|
274
|
+
instruction += `- BACKGROUND: A single, perfectly uniform, PURE SOLID COLOR filling the entire background � ${colorValue}.
|
|
275
|
+
- The background MUST be completely flat and uniform: absolutely NO gradients, NO textures, NO patterns, NO shadows on the background, NO objects, NO surfaces, NO environmental elements.
|
|
276
|
+
- Think of it as a perfectly even studio backdrop paper of exactly this color.
|
|
277
|
+
- The ONLY non-background elements in the image are the subject (jewelry and model if applicable).
|
|
278
|
+
`;
|
|
279
|
+
// Still include non-background scene details (e.g. surface for flatlay)
|
|
280
|
+
if (sceneDetails.length > 0) {
|
|
281
|
+
instruction += `${sceneDetails.map(detailLine => `- ${detailLine}`).join('\n')}\n`;
|
|
164
282
|
}
|
|
165
|
-
|
|
166
|
-
|
|
283
|
+
// Skip: backgroundReference, backgroundType, backgroundTreatment
|
|
284
|
+
// Keep photography style and vibe as they affect lighting/mood, not background content
|
|
285
|
+
if (photographyStyle) {
|
|
286
|
+
instruction += `- Overall Photography Style: ${photographyStyle.value}\n`;
|
|
167
287
|
}
|
|
168
288
|
}
|
|
169
|
-
|
|
170
|
-
|
|
289
|
+
else {
|
|
290
|
+
if (sceneDetails.length > 0) {
|
|
291
|
+
instruction += `${sceneDetails.map(detailLine => `- ${detailLine}`).join('\n')}\n`;
|
|
292
|
+
}
|
|
293
|
+
if (backgroundReference) {
|
|
294
|
+
const referenceLabel = backgroundReference.name ? ` ("${backgroundReference.name}")` : '';
|
|
295
|
+
const orderingNote = hasMuseReferences
|
|
296
|
+
? 'The background reference image is provided after the jewelry and guideline reference images, and BEFORE the final 3 Muse reference images.'
|
|
297
|
+
: 'The background reference image is provided after the jewelry and guideline reference images.';
|
|
298
|
+
instruction += `- Background Image Reference${referenceLabel}: Use the provided background image as the exact background. Preserve its colors, textures, and lighting. Place the jewelry composition on top of that background. ${orderingNote}\n`;
|
|
299
|
+
}
|
|
300
|
+
if (backgroundType && !occasion && !backgroundReference) {
|
|
301
|
+
const bgValue = getRandomBackgroundValue(backgroundType.id, backgroundType.value, !!campaignStyle, allowCampaignAccent);
|
|
302
|
+
instruction += `- Setting Type: ${bgValue}\n`;
|
|
303
|
+
}
|
|
304
|
+
if (background && background.value) {
|
|
305
|
+
const isUserBrandColor = background.value.includes('[USER_BRAND_COLOR]');
|
|
306
|
+
const colorValue = isUserBrandColor ? background.value.replace('[USER_BRAND_COLOR] ', '') : background.value;
|
|
307
|
+
if (template.id === 'flatlay_creative') {
|
|
308
|
+
instruction += isUserBrandColor
|
|
309
|
+
? `- MANDATORY Accent Color: ${colorValue}. The dominant accent tone in the scene MUST match this exact color.\n`
|
|
310
|
+
: `- Secondary accent color/texture element to complement the main material: ${colorValue}\n`;
|
|
311
|
+
}
|
|
312
|
+
else {
|
|
313
|
+
instruction += isUserBrandColor
|
|
314
|
+
? `- MANDATORY Background/Accent Color: ${colorValue}. The background and environment tones MUST prominently feature this exact color.\n`
|
|
315
|
+
: `- Color Palette & Texture: ${colorValue}\n`;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
if (vibe) {
|
|
319
|
+
let vibeValue = vibe.value;
|
|
320
|
+
if (!template.hasModel) {
|
|
321
|
+
vibeValue = vibeValue.replace(/,?\s*shot on [^,]+ lens/gi, '').replace(/\s{2,}/g, ' ').trim();
|
|
322
|
+
}
|
|
323
|
+
if (vibeValue) {
|
|
324
|
+
instruction += `- Mood & Vibes: ${vibeValue}\n`;
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
if (photographyStyle) {
|
|
328
|
+
instruction += `- Overall Photography Style: ${photographyStyle.value}\n`;
|
|
329
|
+
}
|
|
330
|
+
if (hasSettingContext && !backgroundReference) {
|
|
331
|
+
instruction += `\n- Background Treatment: ${getRandomBackgroundTreatment()}\n`;
|
|
332
|
+
}
|
|
171
333
|
}
|
|
172
|
-
instruction += `\nBackground Treatment: ${getRandomBackgroundTreatment()}
|
|
173
|
-
`;
|
|
174
334
|
}
|
|
175
335
|
const LIGHTING_MODES = [
|
|
176
336
|
'Natural light reflections on jewelry (NO artificial sparkles or glow)',
|
|
@@ -179,77 +339,110 @@ The model should look like a natural, real human.
|
|
|
179
339
|
'Gentle overhead diffused studio lighting for authentic material representation',
|
|
180
340
|
'Dramatic chiaroscuro lighting with deep, natural shadows'
|
|
181
341
|
];
|
|
182
|
-
|
|
183
|
-
|
|
342
|
+
let randomLighting = LIGHTING_MODES[Math.floor(Math.random() * LIGHTING_MODES.length)];
|
|
343
|
+
if (photographyStyle?.id === 'sculptural_light') {
|
|
344
|
+
randomLighting = 'Single hard key light from a high angle, crisp shadow edge, controlled specular highlights, studio-grade product lighting';
|
|
345
|
+
}
|
|
184
346
|
instruction += `
|
|
185
|
-
|
|
347
|
+
----------------------------------
|
|
186
348
|
⚙️ TECHNICAL REQUIREMENTS
|
|
187
|
-
|
|
349
|
+
----------------------------------
|
|
188
350
|
- ${randomLighting}
|
|
189
|
-
-
|
|
351
|
+
- Ultra-sharp focus on jewelry; depth-of-field blur applies ONLY to the background
|
|
352
|
+
- Lighting should feel natural with gentle falloff and imperfect shadow edges
|
|
353
|
+
- Optional subtle lens character (light vignetting, mild edge softness) when appropriate
|
|
190
354
|
- Authentic photographic quality (film grain acceptable)
|
|
191
355
|
- Professional color grading
|
|
192
356
|
- 2K resolution output quality
|
|
193
357
|
`;
|
|
194
|
-
|
|
358
|
+
if (template.hasModel) {
|
|
359
|
+
instruction += `- Beauty-retouched skin finish: smooth even tone, reduced pores, minimal blemishes, still realistic (no plastic skin)`;
|
|
360
|
+
}
|
|
195
361
|
if (styleHint) {
|
|
196
362
|
instruction += `
|
|
197
|
-
|
|
363
|
+
|
|
364
|
+
----------------------------------
|
|
198
365
|
🎭 STYLE & POSE DIRECTION
|
|
199
|
-
|
|
200
|
-
${styleHint}
|
|
201
|
-
IMPORTANT: Follow this specific direction to ensure variety across generated images.
|
|
366
|
+
----------------------------------
|
|
367
|
+
- ${styleHint}
|
|
202
368
|
`;
|
|
203
369
|
}
|
|
204
370
|
instruction += `
|
|
205
|
-
|
|
371
|
+
----------------------------------
|
|
206
372
|
🚫 STRICT PROHIBITIONS
|
|
207
|
-
|
|
208
|
-
DO NOT add: fake sparkles, glitter particles, magical glows, lens flares, additional jewelry not in reference
|
|
209
|
-
DO NOT change: the jewelry design, metal type, stone cuts, or any jewelry characteristics
|
|
210
|
-
DO NOT
|
|
211
|
-
DO NOT
|
|
212
|
-
|
|
213
|
-
if (!isBypassMode) {
|
|
214
|
-
instruction += `
|
|
215
|
-
OUTPUT: A structured JSON-like prompt with distinct sections. Do not use a single block of text. Use the following format:
|
|
216
|
-
|
|
217
|
-
{
|
|
218
|
-
"Subject": "Detailed description of the jewelry and model...",
|
|
219
|
-
"Environment": "Setting, background, and atmosphere...",
|
|
220
|
-
"Lighting": "Lighting details...",
|
|
221
|
-
"Photography": "Camera and technical specs..."
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
Ensure the content of each section is rich, dense, and highly descriptive.
|
|
373
|
+
----------------------------------
|
|
374
|
+
- DO NOT add: fake sparkles, glitter particles, magical glows, lens flares, additional jewelry not in reference.
|
|
375
|
+
- DO NOT change: the jewelry design, metal type, stone cuts, or any jewelry characteristics.
|
|
376
|
+
- DO NOT add: scratches, chips, patina, damage, or wear to the jewelry.
|
|
377
|
+
- DO NOT use: artificial effects, over-processing, unrealistic elements.
|
|
378
|
+
- DO NOT generate nudity, semi-nudity or scandalous imagery. The model should be elegantly styled and tastefully posed.
|
|
225
379
|
`;
|
|
380
|
+
if (uploadMode === 'multi_angle') {
|
|
381
|
+
instruction += `- CRITICAL: Do NOT duplicate the jewelry or show multiple instances (no pairs, stacks, or mirrored copies).`;
|
|
226
382
|
}
|
|
383
|
+
instruction += `
|
|
384
|
+
${JEWELRY_MACRO_QUALITY_PROMPT_2}
|
|
385
|
+
`;
|
|
227
386
|
return instruction;
|
|
228
387
|
};
|
|
229
|
-
export const buildSystemInstruction = (template, ethnicity) => {
|
|
388
|
+
export const buildSystemInstruction = (template, ethnicity, imageCount = 1, uploadMode = 'stacking', userGuidelines, hasBackgroundReference = false, hasGuidelineReferences = false, hasMuseReferences = false) => {
|
|
230
389
|
const isFloating = template.id === 'floating_minimal';
|
|
231
390
|
const isFlatlay = template.id === 'flatlay_creative';
|
|
391
|
+
const isSolidColorStudio = template.id === 'solid_color_studio';
|
|
232
392
|
const isHandModel = template.id === 'hand_model';
|
|
233
393
|
const isMuseumExhibit = template.id === 'museum_exhibit';
|
|
234
394
|
const isRomance = template.id === 'romance_proposal';
|
|
235
395
|
const isRomanticMood = template.id === 'romantic_mood';
|
|
236
396
|
let llmSystemInstruction = '';
|
|
397
|
+
let fidelityRule = '';
|
|
398
|
+
if (uploadMode === 'multi_angle') {
|
|
399
|
+
fidelityRule = template.hasModel
|
|
400
|
+
? `1. **JEWELRY FIDELITY (TOP PRIORITY)**: The attached image(s) show the EXACT SAME single piece of jewelry (from different angles).
|
|
401
|
+
- The model must wear ONLY this single piece.
|
|
402
|
+
- Render EXACTLY ONE physical instance of the piece (no duplicates, pairs, stacks, mirrors).
|
|
403
|
+
- Do NOT show multiple angles of the piece within the same image.
|
|
404
|
+
- Synthesize the views into a single coherent piece and choose ONE viewpoint for the output.
|
|
405
|
+
- Do NOT invent new pieces or modify the design.`
|
|
406
|
+
: `1. **JEWELRY FIDELITY (TOP PRIORITY)**: The attached image(s) show the EXACT SAME single piece of jewelry (from different angles).
|
|
407
|
+
- Render EXACTLY ONE physical instance of the piece (no duplicates, pairs, stacks, mirrors).
|
|
408
|
+
- Do NOT show multiple angles of the piece within the same image.
|
|
409
|
+
- Synthesize the views into a single coherent piece and choose ONE viewpoint for the output.
|
|
410
|
+
- Do NOT invent new pieces or modify the design.
|
|
411
|
+
- The jewelry must match the reference images EXACTLY in all details: shape, metal type, stone cuts, chain style, settings, colors, etc. Do NOT change any aspect of the jewelry's appearance.`;
|
|
412
|
+
}
|
|
413
|
+
else if (uploadMode === 'multi_item_single') {
|
|
414
|
+
fidelityRule = `1. **JEWELRY FIDELITY (TOP PRIORITY)**: The attached image shows MULTIPLE distinct jewelry pieces in a single photo.
|
|
415
|
+
- The final image must contain ALL visible pieces together.
|
|
416
|
+
- Each distinct piece must appear EXACTLY ONCE. Do NOT duplicate, mirror, or multiply any piece.
|
|
417
|
+
- Do NOT invent new pieces.
|
|
418
|
+
- Do NOT modify the design of the existing jewelry.
|
|
419
|
+
- THIS IS THE MOST IMPORTANT RULE: The jewelry must match the reference image EXACTLY in all details: shape, metal type, stone cuts, chain style, settings, colors, etc. Do NOT change any aspect of the jewelry's appearance.`;
|
|
420
|
+
}
|
|
421
|
+
else if (imageCount > 1) {
|
|
422
|
+
fidelityRule = `1. **JEWELRY FIDELITY (TOP PRIORITY)**: The final image must contain ALL the jewelry pieces visible in the reference images, styled together.
|
|
423
|
+
- Each distinct piece must appear EXACTLY ONCE. Do NOT duplicate, mirror, or multiply any piece.
|
|
424
|
+
- Do NOT invent new pieces.
|
|
425
|
+
- Do NOT modify the design of the existing jewelry.
|
|
426
|
+
- THIS IS THE MOST IMPORTANT RULE: The jewelry must match the reference images EXACTLY in all details: shape, metal type, stone cuts, chain style, settings, colors, etc. Do NOT change any aspect of the jewelry's appearance.`;
|
|
427
|
+
}
|
|
428
|
+
else {
|
|
429
|
+
fidelityRule = `1. **JEWELRY FIDELITY (TOP PRIORITY)**: The final image must contain ONLY the jewelry piece visible in the reference image.
|
|
430
|
+
- Do NOT invent new pieces (e.g. do not add a necklace if only a ring is provided).
|
|
431
|
+
- Do NOT modify the design of the existing jewelry.
|
|
432
|
+
THIS IS THE MOST IMPORTANT RULE: The jewelry must match the reference image EXACTLY in all details: shape, metal type, stone cuts, chain style, settings, colors, etc. Do NOT change any aspect of the jewelry's appearance.`;
|
|
433
|
+
}
|
|
237
434
|
if (isRomanticMood) {
|
|
238
435
|
llmSystemInstruction = `You are a world-renowned still-life photographer and prop stylist for luxury jewelry and lifestyle brands.
|
|
239
436
|
Generate a DREAMY, INTIMATE STILL-LIFE PHOTOGRAPH of jewelry in a romantic setting.
|
|
240
437
|
|
|
241
438
|
CRITICAL GUIDELINES:
|
|
242
|
-
|
|
243
|
-
- Do NOT invent new pieces.
|
|
244
|
-
- Do NOT modify the design of the existing jewelry.
|
|
439
|
+
${fidelityRule}
|
|
245
440
|
2. **PROP DISCIPLINE (CRITICAL)**: Use ONLY the specific prop/scene described in the user's customization choice. Do NOT add other props.
|
|
246
441
|
- If the user chose "candles", the scene is ONLY candles and the jewelry. Do NOT add roses, letters, or other objects.
|
|
247
442
|
- If the user chose "rose petals", the scene is ONLY rose petals and the jewelry. Do NOT add candles, letters, or other objects.
|
|
248
|
-
- Keep the scene focused and minimal
|
|
443
|
+
- Keep the scene focused and minimal � one prop theme, not a cluttered collection of romantic clich�s.
|
|
249
444
|
3. **Subject**: NO human model, NO body parts, NO mannequins, NO hands.
|
|
250
|
-
4. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Use natural light and genuine material textures
|
|
251
|
-
5. **Realism**: Product photography quality (Hasselblad X2D 100C, 120mm Macro, f/2.8, shallow depth of field). Props must look real and tactile.
|
|
252
|
-
6. **Vibe**: Romantic, intimate, dreamy, feminine.`;
|
|
445
|
+
4. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Use natural light and genuine material textures.`;
|
|
253
446
|
}
|
|
254
447
|
else if (isRomance) {
|
|
255
448
|
const ethnicityPrompt = (ethnicity && ethnicity.id !== 'none') ? ethnicity.value : "Professional couple";
|
|
@@ -257,66 +450,56 @@ export const buildSystemInstruction = (template, ethnicity) => {
|
|
|
257
450
|
Generate an INTIMATE, EMOTIONALLY POWERFUL photograph based on the reference jewelry images.
|
|
258
451
|
|
|
259
452
|
CRITICAL GUIDELINES:
|
|
260
|
-
|
|
261
|
-
- Do NOT invent new pieces (e.g. do not add a necklace if only a ring is provided).
|
|
262
|
-
- Do NOT modify the design of the existing jewelry.
|
|
453
|
+
${fidelityRule}
|
|
263
454
|
2. **Subject**: Focus on the emotional authenticity of the moment. The jewelry (especially rings) should be prominently visible but feel naturally integrated.
|
|
264
455
|
- Hands, fingers, and body language are critical storytelling elements.
|
|
265
456
|
- Ethnicity context: ${ethnicityPrompt}
|
|
266
|
-
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Natural light reflection only
|
|
267
|
-
4. **Realism**: Photography quality (Contax 645, Zeiss Planar 80mm f/2, Kodak Portra 400).
|
|
268
|
-
5. **Vibe**: Tender, authentic, emotionally powerful, intimate. Real love story energy.`;
|
|
457
|
+
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Natural light reflection only.`;
|
|
269
458
|
}
|
|
270
459
|
else if (isMuseumExhibit) {
|
|
271
460
|
llmSystemInstruction = `You are a world-renowned museum photographer and exhibition designer.
|
|
272
461
|
Generate a MUSEUM-QUALITY photograph of jewelry displayed as a priceless exhibit.
|
|
273
462
|
|
|
274
463
|
CRITICAL GUIDELINES:
|
|
275
|
-
|
|
276
|
-
- Do NOT invent new pieces.
|
|
277
|
-
- Do NOT modify the design of the existing jewelry.
|
|
464
|
+
${fidelityRule}
|
|
278
465
|
2. **Subject**: The jewelry should be displayed as a priceless artifact worthy of the world's greatest museums.
|
|
279
466
|
- NO human model, NO body parts, NO mannequins.
|
|
280
|
-
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Professional museum lighting only
|
|
281
|
-
4. **Realism**: Professional museum photography equipment and lighting quality.
|
|
282
|
-
5. **Vibe**: Reverent, prestigious, archival quality, awe-inspiring.`;
|
|
467
|
+
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Professional museum lighting only.`;
|
|
283
468
|
}
|
|
284
469
|
else if (isFloating) {
|
|
285
470
|
llmSystemInstruction = `You are a world-renowned product photographer and creative director for luxury jewelry campaigns.
|
|
286
471
|
Generate a HYPER-REALISTIC product photograph based on the reference images.
|
|
287
472
|
|
|
288
473
|
CRITICAL GUIDELINES:
|
|
289
|
-
|
|
290
|
-
- Do NOT invent new pieces (e.g. do not add earrings if only a necklace is provided).
|
|
291
|
-
- Do NOT modify the design of the existing jewelry.
|
|
474
|
+
${fidelityRule}
|
|
292
475
|
2. **Subject**: The jewelry should appear to be SUSPENDED in mid-air, floating, with NO human model, NO body parts, and NO mannequins. Focus on dramatic lighting, shadows, and a clean, minimalist composition.
|
|
293
|
-
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Natural light reflection only
|
|
294
|
-
|
|
295
|
-
|
|
476
|
+
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Natural light reflection only.`;
|
|
477
|
+
}
|
|
478
|
+
else if (isSolidColorStudio) {
|
|
479
|
+
llmSystemInstruction = `You are a world-renowned product photographer and creative director for luxury jewelry campaigns.
|
|
480
|
+
Generate a HYPER-REALISTIC product photograph based on the reference images.
|
|
481
|
+
|
|
482
|
+
CRITICAL GUIDELINES:
|
|
483
|
+
${fidelityRule}
|
|
484
|
+
2. **Subject**: The jewelry is the ONLY subject. NO human model, NO body parts, NO mannequins, NO props, NO surfaces or platforms.
|
|
485
|
+
3. **Background**: Must be a perfectly uniform solid color exactly as specified by the user prompt. NO gradients, NO textures, NO environmental elements.
|
|
486
|
+
4. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Natural light reflection only.`;
|
|
296
487
|
}
|
|
297
488
|
else if (isFlatlay) {
|
|
298
489
|
llmSystemInstruction = `You are a world-renowned product photographer and creative director for luxury jewelry campaigns.
|
|
299
490
|
Generate a HYPER-REALISTIC product photograph based on the reference images.
|
|
300
491
|
|
|
301
492
|
CRITICAL GUIDELINES:
|
|
302
|
-
|
|
303
|
-
- Do NOT invent new pieces (e.g. do not add earrings if only a necklace is provided).
|
|
304
|
-
- Do NOT modify the design of the existing jewelry.
|
|
493
|
+
${fidelityRule}
|
|
305
494
|
2. **Subject**: The jewelry should be displayed as a creative still-life composition, with NO human model, NO body parts, and NO mannequins.
|
|
306
|
-
|
|
307
|
-
- Lighting should always look natural and photographic — soft studio light, window light, or gentle directional light. Shadows should feel organic, not artificial.
|
|
308
|
-
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow", neon lighting, overly stylized color gels. Natural light reflection only.
|
|
309
|
-
4. **Realism**: Photography quality (Hasselblad X2D 100C, Macro Lens 120mm, f/2.8).
|
|
310
|
-
5. **Vibe**: Old money, elegant, classy, expensive, artistic.`;
|
|
495
|
+
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow", neon lighting, overly stylized color gels. Natural light reflection only.`;
|
|
311
496
|
}
|
|
312
497
|
else if (isHandModel) {
|
|
313
498
|
llmSystemInstruction = `You are a world-renowned product photographer and creative director for luxury jewelry campaigns.
|
|
314
499
|
Generate a HYPER-REALISTIC hand model photograph based on the reference images.
|
|
315
500
|
|
|
316
501
|
CRITICAL GUIDELINES:
|
|
317
|
-
|
|
318
|
-
- Do NOT invent new pieces (e.g. do not add earrings if only a ring is provided).
|
|
319
|
-
- Do NOT modify the design of the existing jewelry.
|
|
502
|
+
${fidelityRule}
|
|
320
503
|
2. **FRAMING (CRITICAL)**: The image focuses on the hand, wrist, and forearm area.
|
|
321
504
|
- NO face, head, or shoulders visible.
|
|
322
505
|
- The forearm may be bare OR elegantly sleeved (luxurious fabrics like silk, cashmere, lace, velvet).
|
|
@@ -324,24 +507,42 @@ export const buildSystemInstruction = (template, ethnicity) => {
|
|
|
324
507
|
3. **Subject**: A model's hand(s) (age 20-30) with elegant, relaxed pose wearing the jewelry. Focus on authentic skin texture and natural nail appearance.
|
|
325
508
|
- If 3 or more jewelry pieces are provided, show BOTH hands to distribute the pieces naturally and elegantly across both hands. Avoid cramming all pieces onto a single hand.
|
|
326
509
|
- If 1-2 pieces, a single hand is fine.
|
|
327
|
-
4. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Natural light reflection only
|
|
328
|
-
5. **Realism**: Photography quality (Hasselblad X2D 100C, Macro Lens 120mm, f/2.8).
|
|
329
|
-
6. **Vibe**: Old money, elegant, classy, expensive, feminine.`;
|
|
510
|
+
4. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Natural light reflection only.`;
|
|
330
511
|
}
|
|
331
512
|
else {
|
|
332
513
|
const ethnicityPrompt = (ethnicity && ethnicity.id !== 'none') ? ethnicity.value : "Professional female model";
|
|
333
514
|
llmSystemInstruction = `You are a world-renowned fashion photographer and creative director for Vogue Arabia and High Jewelry campaigns.
|
|
334
|
-
Generate an AUTHENTIC, CINEMATIC photograph based on the reference images.
|
|
515
|
+
Generate an AUTHENTIC, CINEMATIC photograph based on the reference images. Beauty retouching is desired: smooth even complexion, reduced pores, minimal blemishes; keep a realistic finish and avoid plastic skin.
|
|
335
516
|
|
|
336
517
|
CRITICAL GUIDELINES:
|
|
337
|
-
|
|
338
|
-
- Do NOT invent new pieces (e.g. do not add earrings if only a necklace is provided).
|
|
339
|
-
- Do NOT modify the design of the existing jewelry.
|
|
340
|
-
- If one ring is provided, the model wears ONE ring.
|
|
518
|
+
${fidelityRule}
|
|
341
519
|
2. **Subject**: ALWAYS a ${ethnicityPrompt} (age 20-30).
|
|
342
|
-
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Natural light reflection only
|
|
343
|
-
|
|
344
|
-
|
|
520
|
+
3. **NO FAKE EFFECTS**: Strictly FORBID "sparkles", "glitter particles", "magical glow". Natural light reflection only.`;
|
|
521
|
+
}
|
|
522
|
+
if (userGuidelines && userGuidelines.trim()) {
|
|
523
|
+
llmSystemInstruction += `
|
|
524
|
+
|
|
525
|
+
USER-SPECIFIC GUIDELINES (MUST RESPECT IF ANY ARE PROVIDED):
|
|
526
|
+
${userGuidelines.trim()}
|
|
527
|
+
`;
|
|
528
|
+
}
|
|
529
|
+
llmSystemInstruction += `
|
|
530
|
+
IMPORTANT:
|
|
531
|
+
1. Follow and prioritize the "SETTING & ENVIRONMENT" directives from the user prompt.
|
|
532
|
+
2. Follow and prioritize the "MODEL SPECIFICATIONS" directives from the user prompt.
|
|
533
|
+
3. If an "Overall Photography Style" directive is provided, treat it as a required style constraint.
|
|
534
|
+
4. Only override these style directives if they conflict with jewelry fidelity or explicit prohibitions above.`;
|
|
535
|
+
if (hasGuidelineReferences || hasBackgroundReference || hasMuseReferences) {
|
|
536
|
+
llmSystemInstruction += `
|
|
537
|
+
5. Image reference ordering (important):
|
|
538
|
+
- Jewelry reference images come first.
|
|
539
|
+
- Guideline reference images (if any) come next.
|
|
540
|
+
- Background reference image (if any) comes after guideline references.
|
|
541
|
+
- If Muse images are provided, they are the final 3 images.`;
|
|
542
|
+
}
|
|
543
|
+
if (hasBackgroundReference) {
|
|
544
|
+
llmSystemInstruction += `
|
|
545
|
+
6. The background reference image must be used as the exact background.`;
|
|
345
546
|
}
|
|
346
547
|
return llmSystemInstruction;
|
|
347
548
|
};
|