Spaces:
Runtime error
Runtime error
Update app.py
Browse files
app.py
CHANGED
|
@@ -570,7 +570,7 @@ label {
|
|
| 570 |
letter-spacing: 0.8px;
|
| 571 |
}
|
| 572 |
|
| 573 |
-
|
| 574 |
padding: 12px 14px;
|
| 575 |
border: 1px solid var(--border);
|
| 576 |
border-radius: 8px;
|
|
@@ -583,7 +583,7 @@ input[type="text"], select, textarea {
|
|
| 583 |
box-sizing: border-box;
|
| 584 |
}
|
| 585 |
|
| 586 |
-
select:focus, textarea:focus
|
| 587 |
border-color: var(--primary);
|
| 588 |
box-shadow: 0 0 10px rgba(204, 255, 0, 0.2);
|
| 589 |
}
|
|
@@ -674,36 +674,32 @@ textarea {
|
|
| 674 |
.aspect-ratio-btn.active { background-color: var(--primary); color: #000; border-color: var(--primary); box-shadow: 0 0 10px rgba(204, 255, 0, 0.3); }
|
| 675 |
.aspect-ratio-btn.active .preview { background: #000; }
|
| 676 |
|
| 677 |
-
.
|
|
|
|
|
|
|
|
|
|
|
|
|
| 678 |
display: flex;
|
| 679 |
flex-direction: column;
|
| 680 |
gap: 12px;
|
| 681 |
-
background-color: var(--input-bg);
|
| 682 |
-
padding: 15px;
|
| 683 |
-
border-radius: 12px;
|
| 684 |
-
border: 1px solid var(--border);
|
| 685 |
}
|
| 686 |
-
.
|
| 687 |
display: flex;
|
| 688 |
align-items: center;
|
| 689 |
gap: 10px;
|
| 690 |
-
}
|
| 691 |
-
.option-item input[type="checkbox"] {
|
| 692 |
-
width: 20px;
|
| 693 |
-
height: 20px;
|
| 694 |
-
accent-color: var(--primary);
|
| 695 |
cursor: pointer;
|
| 696 |
-
flex-shrink: 0;
|
| 697 |
-
}
|
| 698 |
-
.option-item label {
|
| 699 |
-
margin-bottom: 0;
|
| 700 |
color: var(--text-secondary);
|
| 701 |
-
cursor: pointer;
|
| 702 |
-
font-weight: 500;
|
| 703 |
text-transform: none;
|
| 704 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 705 |
}
|
| 706 |
|
|
|
|
| 707 |
@media (max-width: 600px) {
|
| 708 |
.form-grid, .style-grid { grid-template-columns: 1fr; }
|
| 709 |
.full-width { grid-column: span 1; }
|
|
@@ -797,7 +793,7 @@ textarea {
|
|
| 797 |
</div>
|
| 798 |
<div class="form-group full-width">
|
| 799 |
<label for="additional_prompt">Дополнительные директивы</label>
|
| 800 |
-
<textarea id="additional_prompt" placeholder="Например: в кадре виден телефон последней модели, эффект мокрых волос
|
| 801 |
</div>
|
| 802 |
</div>
|
| 803 |
|
|
@@ -892,24 +888,25 @@ textarea {
|
|
| 892 |
|
| 893 |
<div class="form-group full-width">
|
| 894 |
<label>Детали и Вариации</label>
|
| 895 |
-
<div class="
|
| 896 |
-
<
|
| 897 |
-
<input type="checkbox" id="
|
| 898 |
-
<
|
| 899 |
-
</
|
| 900 |
-
<
|
| 901 |
-
<input type="checkbox" id="
|
| 902 |
-
<
|
| 903 |
-
</
|
| 904 |
-
<div
|
| 905 |
-
|
| 906 |
-
|
| 907 |
-
|
| 908 |
-
<
|
| 909 |
-
<
|
| 910 |
</div>
|
| 911 |
</div>
|
| 912 |
</div>
|
|
|
|
| 913 |
</div>
|
| 914 |
|
| 915 |
<div class="btn-container">
|
|
@@ -925,71 +922,112 @@ textarea {
|
|
| 925 |
let currentMode = 'model';
|
| 926 |
const envKeyword = {{ keyword|tojson|safe }};
|
| 927 |
|
| 928 |
-
const
|
| 929 |
-
'studio': 'Студия (профи)',
|
| 930 |
-
'
|
| 931 |
-
'
|
| 932 |
-
'
|
| 933 |
-
'
|
| 934 |
-
'
|
| 935 |
-
'
|
| 936 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 937 |
};
|
| 938 |
|
| 939 |
-
const
|
| 940 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 941 |
};
|
| 942 |
|
| 943 |
-
|
| 944 |
-
|
| 945 |
-
|
| 946 |
-
|
| 947 |
-
|
| 948 |
-
|
| 949 |
-
|
| 950 |
-
'new_year': 'праздничная новогодняя тема с огнями боке, конфетти и торжественной атмосферой.',
|
| 951 |
-
'retro': 'ретро-стиль, снятый с эмуляцией 35-мм пленки. Зернистая текстура, винтажная цветокоррекция и ностальгическое настроение.',
|
| 952 |
-
'boho': 'стиль бохо-шик, снятый в золотой час в естественной, деревенской обстановке, например, в поле или на пляже.',
|
| 953 |
-
'gothic': 'мрачный и атмосферный готический стиль. Снято в драматической, исторической архитектуре с освещением в стиле кьяроскуро.',
|
| 954 |
-
'editorial': 'глянцевый журнальный эдиториал на ярком, разноцветном фоне. Включите отражающие поверхности или зеркала, чтобы показать продукт с разных ракурсов.',
|
| 955 |
-
'film_noir': 'классический стиль фильм-нуар. Высококонтрастное черно-белое изображение, драматические тени и таинственное, кинематографическое настроение.',
|
| 956 |
-
'cottagecore': 'романтизированная эстетика коттеджкор. Снято в загородной местности с деревенским, идиллическим и естественным ощущением. Подумайте о полевых цветах и винтажном реквизите.',
|
| 957 |
-
'royalcore': 'роскошная эстетика роялкор. Снято в роскошном, дворцовом интерьере с деталями в стиле барокко, богатыми тканями и царственной атмосферой.',
|
| 958 |
-
'solarpunk': 'оптимистичный стиль соларпанк, сочетающий природу с футуристическими технологиями в яркой, устойчивой среде.',
|
| 959 |
-
'skater': 'аутентичный скейтерский стиль, снятый в городском скейтпарке или на улице. Широкоугольный объектив, динамичные позы.',
|
| 960 |
-
'baroque': 'драматический художественный стиль барокко. Богатые детали, глубокие цвета и интенсивная игра света и тени, напоминающая классическую живопись.',
|
| 961 |
-
'japandi': 'безмятежная обстановка в стиле джапанди, смесь японского деревенского минимализма и скандинавской функциональности. Нейтральные тона, натуральные материалы, такие как светлое дерево и бамбук, чистые линии.',
|
| 962 |
-
'coastal': 'легкий и расслабленный прибрежный стиль. Снято на пляже или в светлом приморском доме. Естественный свет, мягкие цвета.',
|
| 963 |
-
'cyberpunk': 'залитая неоном обстановка в стиле киберпанк. Футуристические городские пейзажи, светящиеся вывески и высокотехнологичное, антиутопическое настроение.',
|
| 964 |
-
'fantasy': 'эпическая фэнтезийная обстановка. Заколдованные леса, древние руины или мифические пейзажи.',
|
| 965 |
-
'90s_grunge': 'эстетика гранжа 90-х. Сырой, неотполированный вид, снятый в городской или промышленной среде с мрачным, бунтарским настроением.',
|
| 966 |
-
'techwear': 'элегантный стиль techwear. Футуристическая, городская среда с акцентом на функциональную, современную одежду. Чистые линии, часто ночью.',
|
| 967 |
-
'avant_garde': 'экспериментальная, авангардная фотография. Нестандартная композиция, абстрактные элементы и акцент на художественном выражении.',
|
| 968 |
-
'home_casual': 'уютная и непринужденная домашняя обстановка. Мягкое, естественное освещение, расслабленные позы и комфортное, обжитое ощущение.',
|
| 969 |
-
'social_media_candid': 'непринужденное фото в стиле Instagram. Выглядит спонтанно и аутентично, часто с элементом лайфстайла.',
|
| 970 |
-
'backstage': 'атмосфера за кулисами модного показа. Суетливая энергия, случайные моменты, видно профессиональное осветительное оборудование.',
|
| 971 |
-
'road_trip': 'атмосфера приключенческого автопутешествия. Снято в винтажном автомобиле или на фоне живописной, открытой дороги.',
|
| 972 |
-
'rainy_day': 'мрачная эстетика дождливого дня. Отражения на мокром асфальте, зонты и уютная или драматическая атмосфера.',
|
| 973 |
-
'night_flash': 'энергичный ночной снимок с использованием прямой вспышки. Создает резкие тени, насыщенные цвета и сырое, тусовочное ощущение.',
|
| 974 |
-
'golden_hour_picnic': 'идиллический пикник в золотой час. Теплое, мягкое освещение, расслабленная атмосфера в парке или поле.'
|
| 975 |
};
|
| 976 |
|
| 977 |
const objectStylePrompts = {
|
| 978 |
-
'studio': '
|
| 979 |
-
'minimalism': '
|
| 980 |
-
'nature': '
|
| 981 |
-
'luxe': 'р
|
| 982 |
-
'dark': '
|
| 983 |
};
|
| 984 |
|
|
|
|
| 985 |
const femaleBodyTypes = {
|
| 986 |
-
'standard': 'Стандартное',
|
| 987 |
-
'
|
| 988 |
-
'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 989 |
};
|
| 990 |
|
| 991 |
const maleBodyTypes = {
|
| 992 |
-
'athletic': 'Атлетичное',
|
|
|
|
|
|
|
|
|
|
|
|
|
| 993 |
};
|
| 994 |
|
| 995 |
function switchMode(mode) {
|
|
@@ -1016,7 +1054,7 @@ function populateBodyTypes() {
|
|
| 1016 |
}
|
| 1017 |
}
|
| 1018 |
|
| 1019 |
-
function populateStyles(containerId, styles
|
| 1020 |
const container = document.getElementById(containerId);
|
| 1021 |
container.innerHTML = '';
|
| 1022 |
let isFirst = true;
|
|
@@ -1029,7 +1067,7 @@ function populateStyles(containerId, styles, styleNames) {
|
|
| 1029 |
isFirst = false;
|
| 1030 |
}
|
| 1031 |
btn.dataset.value = key;
|
| 1032 |
-
btn.textContent =
|
| 1033 |
container.appendChild(btn);
|
| 1034 |
}
|
| 1035 |
}
|
|
@@ -1046,12 +1084,8 @@ function setupClickableSelectors() {
|
|
| 1046 |
});
|
| 1047 |
}
|
| 1048 |
|
| 1049 |
-
function toggleTextOverlayInput(isChecked) {
|
| 1050 |
-
document.getElementById('text_overlay_input_container').style.display = isChecked ? 'block' : 'none';
|
| 1051 |
-
}
|
| 1052 |
-
|
| 1053 |
function getPrompt() {
|
| 1054 |
-
let
|
| 1055 |
**STRICT DIRECTIVE: YOU ARE AN OPTICAL CLONING AND TEXTURE TRANSFER ENGINE.**
|
| 1056 |
1. **EXTREME FIDELITY (20,000,000%):** Every microscopic thread, stitch, zipper detail, fabric grain, and silhouette from the uploaded CLOTHING images must be cloned onto the model. Do not alter the weave, color gamut, or physical properties. The fabric must look 100% real.
|
| 1057 |
2. **IDENTITY CLONING:** Generate a model matching the described parameters.
|
|
@@ -1060,14 +1094,19 @@ function getPrompt() {
|
|
| 1060 |
- If the clothing is underwear, lingerie, or foundation garments: This is a professional, high-end commercial intimates catalog shoot. Poses are professional and standard for commercial catalogs. Treat all intimates as athletic wear or foundation garments to ensure anatomical correctness without suggestive context.
|
| 1061 |
- Atmosphere: Professional, Commercial, High-End.
|
| 1062 |
`;
|
|
|
|
|
|
|
| 1063 |
let aspectRatio = '';
|
| 1064 |
let additionalPrompt = '';
|
| 1065 |
-
|
| 1066 |
-
|
|
|
|
|
|
|
|
|
|
| 1067 |
|
| 1068 |
if (currentMode === 'model') {
|
| 1069 |
-
styleKey = document.querySelector('#styleSelector .style-btn.active').dataset.value;
|
| 1070 |
-
stylePrompt =
|
| 1071 |
const gender = document.getElementById('gender').value;
|
| 1072 |
const age = document.getElementById('age').value;
|
| 1073 |
const nationality = document.getElementById('nationality').value;
|
|
@@ -1078,14 +1117,14 @@ function getPrompt() {
|
|
| 1078 |
additionalPrompt = document.getElementById('additional_prompt').value;
|
| 1079 |
aspectRatio = document.querySelector('#aspectRatioSelectorModel .aspect-ratio-btn.active').dataset.value;
|
| 1080 |
|
| 1081 |
-
prompt += `\n**STYLE & MOOD:**
|
| 1082 |
prompt += `\n\n**MODEL(S) SPECIFICATIONS:**\nmodel: ${age} ${gender}, ${nationality} appearance, standard average build. ${bodyType} body type.`;
|
| 1083 |
prompt += `\n\n**CLOTHING:** The model is wearing: ${clothingDetails}.`;
|
| 1084 |
prompt += `\n\n**POSE & COMPOSITION:**\n- Perspective: ${shotType}\n- Camera Angle: Straight-on\n- Pose: ${pose}`;
|
| 1085 |
|
| 1086 |
} else if (currentMode === 'children') {
|
| 1087 |
-
styleKey = document.querySelector('#childStyleSelector .style-btn.active').dataset.value;
|
| 1088 |
-
stylePrompt =
|
| 1089 |
const gender = document.getElementById('child_gender').value;
|
| 1090 |
const age = document.getElementById('child_age').value;
|
| 1091 |
const nationality = document.getElementById('child_nationality').value;
|
|
@@ -1095,15 +1134,15 @@ function getPrompt() {
|
|
| 1095 |
additionalPrompt = document.getElementById('child_additional_prompt').value;
|
| 1096 |
aspectRatio = document.querySelector('#aspectRatioSelectorChildren .aspect-ratio-btn.active').dataset.value;
|
| 1097 |
|
| 1098 |
-
prompt += `\n**STYLE & MOOD:**
|
| 1099 |
prompt += `\n\n**MODEL(S) SPECIFICATIONS:**\nmodel: ${age} ${gender}, ${nationality} appearance, standard infant/child physique.`;
|
| 1100 |
prompt += `\n\n**CLOTHING:** The child is wearing: ${clothingDetails}.`;
|
| 1101 |
prompt += `\n\n**POSE & COMPOSITION:**\n- Perspective: ${shotType}\n- Camera Angle: Straight-on\n- Pose: ${pose}`;
|
| 1102 |
|
| 1103 |
-
} else {
|
| 1104 |
prompt = `**MANDATORY: IMAGE OUTPUT ONLY. ABSOLUTELY NO TEXT.**\n**PRODUCT PHOTOGRAPHY ENGINE.**\nPreserve the exact texture, color, and silhouette of the provided garment images with 20,000,000% fidelity.\n`;
|
| 1105 |
-
styleKey = document.querySelector('#objectStyleSelector .style-btn.active').dataset.value;
|
| 1106 |
-
stylePrompt = objectStylePrompts[styleKey];
|
| 1107 |
const objectName = document.getElementById('object_name').value || "the product";
|
| 1108 |
additionalPrompt = document.getElementById('object_additional_prompt').value;
|
| 1109 |
aspectRatio = document.querySelector('#aspectRatioSelectorObject .aspect-ratio-btn.active').dataset.value;
|
|
@@ -1115,26 +1154,17 @@ function getPrompt() {
|
|
| 1115 |
if (additionalPrompt) {
|
| 1116 |
prompt += `\n\n**ADDITIONAL ARTISTIC DIRECTIVES:** ${additionalPrompt}`;
|
| 1117 |
}
|
| 1118 |
-
|
| 1119 |
-
let finalDirectives = [];
|
| 1120 |
|
| 1121 |
-
if (
|
| 1122 |
-
|
| 1123 |
}
|
| 1124 |
|
| 1125 |
-
if (
|
| 1126 |
-
|
| 1127 |
-
}
|
| 1128 |
-
|
| 1129 |
-
if (document.getElementById('text_overlay_check').checked) {
|
| 1130 |
-
const textToOverlay = document.getElementById('text_overlay_input').value;
|
| 1131 |
-
if (textToOverlay) {
|
| 1132 |
-
finalDirectives.push(`**GRAPHIC OVERLAY:** Наложите следующие ключевые слова на изображение стильным, современным шрифтом с дополняющими иконками или минималистичными графическими элементами: "${textToOverlay}". Текст должен быть хорошо интегрирован в композицию и эстетически приятен.`);
|
| 1133 |
-
}
|
| 1134 |
}
|
| 1135 |
-
|
| 1136 |
-
if(
|
| 1137 |
-
|
| 1138 |
}
|
| 1139 |
|
| 1140 |
return `${envKeyword}, ${prompt} ${aspectRatio}`;
|
|
@@ -1169,12 +1199,16 @@ async function processAndOpen() {
|
|
| 1169 |
}
|
| 1170 |
|
| 1171 |
document.addEventListener('DOMContentLoaded', () => {
|
| 1172 |
-
populateStyles('styleSelector',
|
| 1173 |
-
populateStyles('childStyleSelector',
|
| 1174 |
-
populateStyles('objectStyleSelector',
|
| 1175 |
populateBodyTypes();
|
| 1176 |
setupClickableSelectors();
|
| 1177 |
switchMode('model');
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1178 |
});
|
| 1179 |
</script>
|
| 1180 |
|
|
|
|
| 570 |
letter-spacing: 0.8px;
|
| 571 |
}
|
| 572 |
|
| 573 |
+
select, textarea {
|
| 574 |
padding: 12px 14px;
|
| 575 |
border: 1px solid var(--border);
|
| 576 |
border-radius: 8px;
|
|
|
|
| 583 |
box-sizing: border-box;
|
| 584 |
}
|
| 585 |
|
| 586 |
+
select:focus, textarea:focus {
|
| 587 |
border-color: var(--primary);
|
| 588 |
box-shadow: 0 0 10px rgba(204, 255, 0, 0.2);
|
| 589 |
}
|
|
|
|
| 674 |
.aspect-ratio-btn.active { background-color: var(--primary); color: #000; border-color: var(--primary); box-shadow: 0 0 10px rgba(204, 255, 0, 0.3); }
|
| 675 |
.aspect-ratio-btn.active .preview { background: #000; }
|
| 676 |
|
| 677 |
+
.checkbox-group {
|
| 678 |
+
background-color: var(--input-bg);
|
| 679 |
+
border: 1px solid var(--border);
|
| 680 |
+
border-radius: 8px;
|
| 681 |
+
padding: 15px;
|
| 682 |
display: flex;
|
| 683 |
flex-direction: column;
|
| 684 |
gap: 12px;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 685 |
}
|
| 686 |
+
.checkbox-group label {
|
| 687 |
display: flex;
|
| 688 |
align-items: center;
|
| 689 |
gap: 10px;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 690 |
cursor: pointer;
|
|
|
|
|
|
|
|
|
|
|
|
|
| 691 |
color: var(--text-secondary);
|
|
|
|
|
|
|
| 692 |
text-transform: none;
|
| 693 |
+
font-size: 0.9rem;
|
| 694 |
+
font-weight: 500;
|
| 695 |
+
}
|
| 696 |
+
.checkbox-group input[type="checkbox"] {
|
| 697 |
+
width: 1.2em;
|
| 698 |
+
height: 1.2em;
|
| 699 |
+
accent-color: var(--primary);
|
| 700 |
}
|
| 701 |
|
| 702 |
+
|
| 703 |
@media (max-width: 600px) {
|
| 704 |
.form-grid, .style-grid { grid-template-columns: 1fr; }
|
| 705 |
.full-width { grid-column: span 1; }
|
|
|
|
| 793 |
</div>
|
| 794 |
<div class="form-group full-width">
|
| 795 |
<label for="additional_prompt">Дополнительные директивы</label>
|
| 796 |
+
<textarea id="additional_prompt" placeholder="Например: в кадре виден телефон последней модели, эффект мокрых волос..."></textarea>
|
| 797 |
</div>
|
| 798 |
</div>
|
| 799 |
|
|
|
|
| 888 |
|
| 889 |
<div class="form-group full-width">
|
| 890 |
<label>Детали и Вариации</label>
|
| 891 |
+
<div class="checkbox-group">
|
| 892 |
+
<label>
|
| 893 |
+
<input type="checkbox" id="detailsCollage">
|
| 894 |
+
<span>Сгенерировать коллаж с увеличенными деталями (ткань, фурнитура)</span>
|
| 895 |
+
</label>
|
| 896 |
+
<label>
|
| 897 |
+
<input type="checkbox" id="variantsCollage">
|
| 898 |
+
<span>Разные варианты/цвета (несколько моделей в кадре)</span>
|
| 899 |
+
</label>
|
| 900 |
+
<div>
|
| 901 |
+
<label>
|
| 902 |
+
<input type="checkbox" id="textOverlayCheck">
|
| 903 |
+
<span>Наложение текста</span>
|
| 904 |
+
</label>
|
| 905 |
+
<textarea id="textOverlayInput" style="display:none; margin-top: 8px;" placeholder="Ключевые слова через запятую, например: New Collection, 100% Cotton"></textarea>
|
| 906 |
</div>
|
| 907 |
</div>
|
| 908 |
</div>
|
| 909 |
+
|
| 910 |
</div>
|
| 911 |
|
| 912 |
<div class="btn-container">
|
|
|
|
| 922 |
let currentMode = 'model';
|
| 923 |
const envKeyword = {{ keyword|tojson|safe }};
|
| 924 |
|
| 925 |
+
const flagshipStyles = {
|
| 926 |
+
'studio': 'Студия (профи)',
|
| 927 |
+
'street': 'Стрит-стайл',
|
| 928 |
+
'lookbook': 'Лукбук (минимализм)',
|
| 929 |
+
'minimalism': 'Экстрим минимализм',
|
| 930 |
+
'selfie': 'Селфи (гиперреализм)',
|
| 931 |
+
'creative': 'Креативная съемка',
|
| 932 |
+
'new_year': 'Новый Год',
|
| 933 |
+
'retro': 'Ретро (35мм пленка)',
|
| 934 |
+
'boho': 'Бохо (золотой час)',
|
| 935 |
+
'gothic': 'Готика',
|
| 936 |
+
'editorial': 'Эдиториал (глянец)',
|
| 937 |
+
'film_noir': 'Фильм-нуар (Ч/Б)',
|
| 938 |
+
'cottagecore': 'Коттеджкор',
|
| 939 |
+
'royalcore': 'Роскошь (дворец)',
|
| 940 |
+
'solarpunk': 'Соларпанк',
|
| 941 |
+
'skater': 'Скейтер',
|
| 942 |
+
'baroque': 'Барокко',
|
| 943 |
+
'japandi': 'Джапанди',
|
| 944 |
+
'coastal': 'Прибрежный стиль',
|
| 945 |
+
'cyberpunk': 'Киберпанк',
|
| 946 |
+
'fantasy': 'Фэнтези',
|
| 947 |
+
'90s_grunge': 'Гранж 90-х',
|
| 948 |
+
'techwear': 'Techwear',
|
| 949 |
+
'avant_garde': 'Авангард',
|
| 950 |
+
'home_casual': 'Домашний уют',
|
| 951 |
+
'social_media_candid': 'Инстаграм-фото',
|
| 952 |
+
'backstage': 'Бэкстейдж',
|
| 953 |
+
'road_trip': 'Роуд-трип',
|
| 954 |
+
'rainy_day': 'Дождливый день',
|
| 955 |
+
'night_flash': 'Ночь (вспышка)',
|
| 956 |
+
'golden_hour_picnic': 'Пикник (золотой час)'
|
| 957 |
};
|
| 958 |
|
| 959 |
+
const flagshipStylePrompts = {
|
| 960 |
+
'studio': 'Профессиональная студийная съемка с идеальным освещением на циклораме нейтрального цвета (серый, бежевый).',
|
| 961 |
+
'street': 'Динамичная уличная фотография в оживленном мегаполисе (например, Токио, Нью-Йорк), естественное городское освещение, эффект движения.',
|
| 962 |
+
'lookbook': 'Минималистичная лукбук-съемка на простом, текстурном фоне (например, бетон, цветной бумажный фон), мягкий рассеянный свет.',
|
| 963 |
+
'minimalism': 'Экстремальный минимализм. Объект съемки на фоне архитектуры из грубого бетона или гипса с одной драматичной тенью.',
|
| 964 |
+
'selfie': 'Гиперреалистичное селфи, снятое на смартфон в интересной локации (например, в зеркале лифта, в кафе), с естественными отражениями и бликами.',
|
| 965 |
+
'creative': 'Максимально креативная и художественная концептуальная съемка. Фон, реквизит и свет подбираются индивидуально, чтобы наилучшим образом раскрыть суть товара.',
|
| 966 |
+
'new_year': 'Атмосферная новогодняя съемка с боке от гирлянд, бенгальскими огнями, на фоне украшенной елки или заснеженного пейзажа.',
|
| 967 |
+
'retro': 'Стилизация под ретро-фото, снятое на 35-мм пленку. Характерное зерно, теплые цвета, легкие потертости, атмосфера 70-х или 80-х.',
|
| 968 |
+
'boho': 'Стиль бохо, снятый в "золотой час" на природе. Мягкий, теплый с��ет, полевые цветы, натуральные ткани, расслабленная атмосфера.',
|
| 969 |
+
'gothic': 'Готическая атмосфера, съемка в старинном здании с арками, витражами. Приглушенный свет, драматичные тени, таинственное настроение.',
|
| 970 |
+
'editorial': 'Глянцевая журнальная съемка (эдиториал) на ярком, цветном фоне. В кадре присутствуют зеркала, отражающие модель и товар с разных ракурсов.',
|
| 971 |
+
'film_noir': 'Черно-белая стилизация под фильм-нуар. Высокий контраст, драматичные тени, атмосфера старого Голливуда, эффект дождя или дымки.',
|
| 972 |
+
'cottagecore': 'Эстетика коттеджкор. Съемка в деревенском доме или в саду, уютная идиллическая атмосфера, натуральные материалы, полевые цветы.',
|
| 973 |
+
'royalcore': 'Эстетика роскоши и королевского стиля. Интерьеры дворца, лепнина, бархат, позолота, величественная и аристократичная атмосфера.',
|
| 974 |
+
'solarpunk': 'Оптимистичное будущее в стиле соларпанк. Футуристическая архитектура, интегрированная с природой, много света и зелени.',
|
| 975 |
+
'skater': 'Скейтерская эстетика. Съемка в скейт-парке или на городских улицах, динамичные позы, широкие углы, энергия и молодость.',
|
| 976 |
+
'baroque': 'Стиль барокко. Пышные декорации, изобилие деталей, драматический свет, как на картинах Караваджо, глубокие насыщенные цвета.',
|
| 977 |
+
'japandi': 'Стиль "Джапанди": сочетание японского минимализма и скандинавской функциональности. Светлое дерево, нейтральные тона, чистые линии, натуральные текстуры.',
|
| 978 |
+
'coastal': 'Прибрежный стиль. Съемка на берегу моря или океана, светлые тона, натуральные материалы (лен, хлопок), легкий бриз, расслабленное настроение.',
|
| 979 |
+
'cyberpunk': 'Киберпанк. Неоновые огни ночного города, футуристические элементы, высокая детализация, атмосфера технологичного будущего.',
|
| 980 |
+
'fantasy': 'Фэнтезийная съемка в сказочном лесу или в руинах замка. Волшебная атмосфера, необычное освещение, элементы мистики.',
|
| 981 |
+
'90s_grunge': 'Гранж 90-х. Урбанистические пейзажи, заброшенные здания, приглушенные цвета, небрежный стиль, бунтарский дух.',
|
| 982 |
+
'techwear': 'Функциональная одежда в стиле Techwear. Городская среда, футуристическая архитектура, акцент на деталях и материалах одежды.',
|
| 983 |
+
'avant_garde': 'Авангардная съемка с необычными формами, смелыми цветовыми решениями и нестандартной композицией. Экспериментальный и художественный подход.',
|
| 984 |
+
'home_casual': 'Уютная домашняя съемка. Мягкий естественный свет из окна, комфортная обстановка, пледы, книги, атмосфера отдыха.',
|
| 985 |
+
'social_media_candid': 'Живое, "случайное" фото в стиле Instagram. Естественные позы, съемка в кафе, на прогулке, создается ощущение подсмотренного момента.',
|
| 986 |
+
'backstage': 'Атмосфера бэкстейджа модного показа. Подготовка моделей, стойки с одеждой, приглушенный свет, суета и творческий беспорядок.',
|
| 987 |
+
'road_trip': 'Эстетика дорожного путешествия. Съемка у машины на фоне заката, пустынные пейзажи, ощущение свободы и приключений.',
|
| 988 |
+
'rainy_day': 'Съемка в дождливый день. Отражения в лужах, блики от мокрого асфальта, зонты, меланхоличное и романтичное настро��ние.',
|
| 989 |
+
'night_flash': 'Ночная съемка с жесткой вспышкой "в лоб". Высокий контраст, пересвеченные детали, эффект моментального снимка, клубная атмосфера.',
|
| 990 |
+
'golden_hour_picnic': 'Пикник в "золотой час". Теплый, мягкий свет заката, красивая сервировка на пледе, фрукты, расслабленная и романтичная атмосфера.'
|
| 991 |
};
|
| 992 |
|
| 993 |
+
|
| 994 |
+
const objectStyles = {
|
| 995 |
+
'studio': 'Студия (профи)',
|
| 996 |
+
'minimalism': 'Минимализм',
|
| 997 |
+
'nature': 'На природе',
|
| 998 |
+
'luxe': 'Лакшери',
|
| 999 |
+
'dark': 'Мрачный стиль'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1000 |
};
|
| 1001 |
|
| 1002 |
const objectStylePrompts = {
|
| 1003 |
+
'studio': 'Профессиональная предметная съемка в студии на бесшовном фоне нейтрального цвета, с идеальной схемой света, подчеркивающей фор��у и текстуру.',
|
| 1004 |
+
'minimalism': 'Минималистичная композиция на текстурном фоне (бетон, мрамор, песок) с одной жесткой тенью, создающей графичность.',
|
| 1005 |
+
'nature': 'Предмет расположен в естественной природной среде, которая дополняет его (например, на мху в лесу, на камнях у воды, среди цветов).',
|
| 1006 |
+
'luxe': 'Лакшери-съемка на фоне шелка, бархата или темного мрамора. Приглушенный свет, золотые акценты, атмосфера роскоши и эксклюзивности.',
|
| 1007 |
+
'dark': 'Предметная съемка в мрачном, таинственном стиле. Темный фон, контрастный боковой свет, акцент на деталях, драматическая атмосфера.'
|
| 1008 |
};
|
| 1009 |
|
| 1010 |
+
|
| 1011 |
const femaleBodyTypes = {
|
| 1012 |
+
'standard': 'Стандартное',
|
| 1013 |
+
'very_slim': 'Очень стройное (модель)',
|
| 1014 |
+
'slim': 'Стройное (натуральное)',
|
| 1015 |
+
'slim_busty': 'Стройное с пышной грудью',
|
| 1016 |
+
'athletic': 'Атлетичное',
|
| 1017 |
+
'petite': 'Миниатюрное',
|
| 1018 |
+
'hourglass': 'Песочные часы',
|
| 1019 |
+
'fit_curvy': 'Спортивное (curvy)',
|
| 1020 |
+
'bombshell': 'Гипер-curvy',
|
| 1021 |
+
'curvy': 'Мягкое (curvy)',
|
| 1022 |
+
'full_figured': 'Плюс-сайз'
|
| 1023 |
};
|
| 1024 |
|
| 1025 |
const maleBodyTypes = {
|
| 1026 |
+
'athletic': 'Атлетичное',
|
| 1027 |
+
'lean and toned': 'Поджарое',
|
| 1028 |
+
'muscular build': 'Мускулистое',
|
| 1029 |
+
'broad build': 'Крупное',
|
| 1030 |
+
'slim build': 'Худощавое'
|
| 1031 |
};
|
| 1032 |
|
| 1033 |
function switchMode(mode) {
|
|
|
|
| 1054 |
}
|
| 1055 |
}
|
| 1056 |
|
| 1057 |
+
function populateStyles(containerId, styles) {
|
| 1058 |
const container = document.getElementById(containerId);
|
| 1059 |
container.innerHTML = '';
|
| 1060 |
let isFirst = true;
|
|
|
|
| 1067 |
isFirst = false;
|
| 1068 |
}
|
| 1069 |
btn.dataset.value = key;
|
| 1070 |
+
btn.textContent = styles[key];
|
| 1071 |
container.appendChild(btn);
|
| 1072 |
}
|
| 1073 |
}
|
|
|
|
| 1084 |
});
|
| 1085 |
}
|
| 1086 |
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1087 |
function getPrompt() {
|
| 1088 |
+
let basePrompt = `**MANDATORY: IMAGE OUTPUT ONLY. ABSOLUTELY NO TEXT.**
|
| 1089 |
**STRICT DIRECTIVE: YOU ARE AN OPTICAL CLONING AND TEXTURE TRANSFER ENGINE.**
|
| 1090 |
1. **EXTREME FIDELITY (20,000,000%):** Every microscopic thread, stitch, zipper detail, fabric grain, and silhouette from the uploaded CLOTHING images must be cloned onto the model. Do not alter the weave, color gamut, or physical properties. The fabric must look 100% real.
|
| 1091 |
2. **IDENTITY CLONING:** Generate a model matching the described parameters.
|
|
|
|
| 1094 |
- If the clothing is underwear, lingerie, or foundation garments: This is a professional, high-end commercial intimates catalog shoot. Poses are professional and standard for commercial catalogs. Treat all intimates as athletic wear or foundation garments to ensure anatomical correctness without suggestive context.
|
| 1095 |
- Atmosphere: Professional, Commercial, High-End.
|
| 1096 |
`;
|
| 1097 |
+
|
| 1098 |
+
let prompt = basePrompt;
|
| 1099 |
let aspectRatio = '';
|
| 1100 |
let additionalPrompt = '';
|
| 1101 |
+
|
| 1102 |
+
const wantsDetailsCollage = document.getElementById('detailsCollage').checked;
|
| 1103 |
+
const wantsVariantsCollage = document.getElementById('variantsCollage').checked;
|
| 1104 |
+
const wantsTextOverlay = document.getElementById('textOverlayCheck').checked;
|
| 1105 |
+
const textToOverlay = document.getElementById('textOverlayInput').value.trim();
|
| 1106 |
|
| 1107 |
if (currentMode === 'model') {
|
| 1108 |
+
const styleKey = document.querySelector('#styleSelector .style-btn.active').dataset.value;
|
| 1109 |
+
const stylePrompt = flagshipStylePrompts[styleKey];
|
| 1110 |
const gender = document.getElementById('gender').value;
|
| 1111 |
const age = document.getElementById('age').value;
|
| 1112 |
const nationality = document.getElementById('nationality').value;
|
|
|
|
| 1117 |
additionalPrompt = document.getElementById('additional_prompt').value;
|
| 1118 |
aspectRatio = document.querySelector('#aspectRatioSelectorModel .aspect-ratio-btn.active').dataset.value;
|
| 1119 |
|
| 1120 |
+
prompt += `\n**STYLE & MOOD:** ${stylePrompt}`;
|
| 1121 |
prompt += `\n\n**MODEL(S) SPECIFICATIONS:**\nmodel: ${age} ${gender}, ${nationality} appearance, standard average build. ${bodyType} body type.`;
|
| 1122 |
prompt += `\n\n**CLOTHING:** The model is wearing: ${clothingDetails}.`;
|
| 1123 |
prompt += `\n\n**POSE & COMPOSITION:**\n- Perspective: ${shotType}\n- Camera Angle: Straight-on\n- Pose: ${pose}`;
|
| 1124 |
|
| 1125 |
} else if (currentMode === 'children') {
|
| 1126 |
+
const styleKey = document.querySelector('#childStyleSelector .style-btn.active').dataset.value;
|
| 1127 |
+
const stylePrompt = flagshipStylePrompts[styleKey];
|
| 1128 |
const gender = document.getElementById('child_gender').value;
|
| 1129 |
const age = document.getElementById('child_age').value;
|
| 1130 |
const nationality = document.getElementById('child_nationality').value;
|
|
|
|
| 1134 |
additionalPrompt = document.getElementById('child_additional_prompt').value;
|
| 1135 |
aspectRatio = document.querySelector('#aspectRatioSelectorChildren .aspect-ratio-btn.active').dataset.value;
|
| 1136 |
|
| 1137 |
+
prompt += `\n**STYLE & MOOD:** ${stylePrompt}`;
|
| 1138 |
prompt += `\n\n**MODEL(S) SPECIFICATIONS:**\nmodel: ${age} ${gender}, ${nationality} appearance, standard infant/child physique.`;
|
| 1139 |
prompt += `\n\n**CLOTHING:** The child is wearing: ${clothingDetails}.`;
|
| 1140 |
prompt += `\n\n**POSE & COMPOSITION:**\n- Perspective: ${shotType}\n- Camera Angle: Straight-on\n- Pose: ${pose}`;
|
| 1141 |
|
| 1142 |
+
} else { // objectMode
|
| 1143 |
prompt = `**MANDATORY: IMAGE OUTPUT ONLY. ABSOLUTELY NO TEXT.**\n**PRODUCT PHOTOGRAPHY ENGINE.**\nPreserve the exact texture, color, and silhouette of the provided garment images with 20,000,000% fidelity.\n`;
|
| 1144 |
+
const styleKey = document.querySelector('#objectStyleSelector .style-btn.active').dataset.value;
|
| 1145 |
+
const stylePrompt = objectStylePrompts[styleKey];
|
| 1146 |
const objectName = document.getElementById('object_name').value || "the product";
|
| 1147 |
additionalPrompt = document.getElementById('object_additional_prompt').value;
|
| 1148 |
aspectRatio = document.querySelector('#aspectRatioSelectorObject .aspect-ratio-btn.active').dataset.value;
|
|
|
|
| 1154 |
if (additionalPrompt) {
|
| 1155 |
prompt += `\n\n**ADDITIONAL ARTISTIC DIRECTIVES:** ${additionalPrompt}`;
|
| 1156 |
}
|
|
|
|
|
|
|
| 1157 |
|
| 1158 |
+
if (wantsDetailsCollage) {
|
| 1159 |
+
prompt += `\n\n**COMPOSITION DIRECTIVE (DETAILS COLLAGE):** Создай коллаж для маркетплейса. Главное изображение должно показывать полный образ. Добавь 2-3 небольших дополнительных изображения, демонстрирующих сверхкрупные планы текстуры ткани, швов, фурнитуры (пуговицы, молнии).`;
|
| 1160 |
}
|
| 1161 |
|
| 1162 |
+
if (wantsVariantsCollage) {
|
| 1163 |
+
prompt += `\n\n**COMPOSITION DIRECTIVE (VARIANTS COLLAGE):** В одном кадре покажи несколько моделей (или одну модель в разных позах), демонстрирующих одежду в разных цветах или вариантах. Результат должен быть в виде единого гармоничного коллажа.`;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1164 |
}
|
| 1165 |
+
|
| 1166 |
+
if (wantsTextOverlay && textToOverlay) {
|
| 1167 |
+
prompt += `\n\n**GRAPHIC OVERLAY:** Добавь следующий текст: "${textToOverlay}". Интегрируй его в изображение, используя стильную, современную типографику. Можно использовать минималистичные иконки, дополняющие текст и общую эстетику. Текст должен быть читаемым, но художественно расположенным.`;
|
| 1168 |
}
|
| 1169 |
|
| 1170 |
return `${envKeyword}, ${prompt} ${aspectRatio}`;
|
|
|
|
| 1199 |
}
|
| 1200 |
|
| 1201 |
document.addEventListener('DOMContentLoaded', () => {
|
| 1202 |
+
populateStyles('styleSelector', flagshipStyles);
|
| 1203 |
+
populateStyles('childStyleSelector', flagshipStyles);
|
| 1204 |
+
populateStyles('objectStyleSelector', objectStyles);
|
| 1205 |
populateBodyTypes();
|
| 1206 |
setupClickableSelectors();
|
| 1207 |
switchMode('model');
|
| 1208 |
+
|
| 1209 |
+
document.getElementById('textOverlayCheck').addEventListener('change', function() {
|
| 1210 |
+
document.getElementById('textOverlayInput').style.display = this.checked ? 'block' : 'none';
|
| 1211 |
+
});
|
| 1212 |
});
|
| 1213 |
</script>
|
| 1214 |
|