edit_api.py:

•
SAM2 fix — switched to SAM2ImagePredictor with a generous bbox (5% margin) instead of points. Bbox-based SAM2 captures the full subject including hair, glasses, and sandals since it doesn't clip with negative-point interference
•
Non-destructive remove-bg — writes <stem>.nobg.png sidecar, original file untouched; registers sidecar in DB under same group
•
New /images/{filename}/duplicate endpoint — copies file with a fresh timestamp name, same group
car.html:
•
sam2RemoveBg() — switches viewer to sidecar URL, auto-enables checkerboard; original file never modified
•
restoreBg() — purely client-side, reverts viewer to original URL (no API call, no file change)
•
Gallery cycling frozen while studio is open (guard in startGroupCycle interval callback)
•
Main page scrollbar hidden when studio opens (body.overflow = hidden), restored on close
•
Delete — two-step inline confirmation: first click arms the button red ("Confirm delete"), second click deletes; stays in studio and navigates to the next image; only closes if it was the last image in the group
•
Duplicate button in Info tab — copies image into same group and navigates to the duplicate immediately
This commit is contained in:
mike
2026-06-22 11:58:51 +02:00
parent 7beed86c9a
commit 8dfe7775ea
7 changed files with 2379 additions and 127 deletions

View File

@@ -12,7 +12,13 @@ groups.json
config
videos
prompts should be viisible in studio view
copied artefacts should cary references
flag beta poses in ui
delete button gets disabled after a delete
extract a frame from a clip (scenery)
faceswap defaults nothing enabled, see jobs even when refresh

View File

@@ -3,13 +3,6 @@ A realistic artistic nude female.
The model kneels on all fours with hands planted firmly under the shoulders and knees directly under the hips. One arm and the opposite leg are lifted completely off the ground, creating a powerful diagonal stretch across the body. Hips are lowered toward the ground. The composition emphasizes the muscular tension in the lifted limbs and the continuous curved lines of the arched back and torso. Strength and dynamic energy radiate from the pose. Studio lighting, anatomically precise, no background, plain neutral backdrop, high detail, professional figure reference photography.
# The Butterfly2:
Lays down with knees bent and feet touching, soles of feet pressed together in butterfly pose.
Clasp your hands around your legs and pull your feet up towards your chest.
Extend one leg over the other.
Head on top.
Realistic, perfect anatomy
# The Kneeling (Dynamic):
kneeling on all fours, hands under shoulders, knees under hips.
one arm and opposite leg slightly lifted off the ground, creating diagonal tension.
@@ -25,3 +18,43 @@ legs extended straight behind, toes pointed.
head lowered, face turned down toward the ground, chin tucked.
Looking down, not at camera. Regal, poised.
Perfect anatomy, realistic
# The Ascension (beta):
lying on back.
arms extended overhead, hands clasped or reaching past the head.
legs lifted straight up together, fully extended toward ceiling.
lower back pressed flat to the ground, shoulders relaxed.
vertical line from shoulders through heels.
Looking directly into camera. Weightless, transcendent.
Perfect anatomy, realistic
# The Sickle (beta):
lying on back, legs lifted and bent.
knees drawing toward the chest, then extending and lowering toward the head.
feet arched, toes pointing toward the ground behind the head.
arms wrapped around the thighs or extended to the sides.
body folded tightly, spine compressed.
Looking at the knees, then into camera. Curved, hooked.
Perfect anatomy, realistic
---
# The Hogtie:
lying on stomach, wrists bound behind the back.
ankles bound together, drawn toward the bound wrists.
body arched backward, chest and thighs lifted slightly off the ground.
head turned to the side, cheek on the ground.
Looking directly into camera. Contorted, helpless.
Perfect anatomy, realistic
---
# The Spread Eagle (Restrained):
lying on back, arms extended straight out to the sides, wrists bound to implied anchors.
legs spread wide, ankles bound to implied anchors.
back flat on the ground, hips centered.
head tilted back, throat exposed.
Looking upward, not at camera. Vulnerable, displayed.
Perfect anatomy, realistic

View File

@@ -1183,6 +1183,7 @@
border-radius: 50%;
animation: spin 0.8s linear infinite;
flex-shrink: 0;
will-change: transform;
}
.fs-options {
display: flex;
@@ -1400,6 +1401,7 @@
border-top-color: #2563eb; border-radius: 50%;
animation: spin 0.8s linear infinite; display: inline-block;
margin-right: 4px; vertical-align: middle;
will-change: transform;
}
.sb-source-refs { display: flex; flex-wrap: wrap; gap: 4px; margin-top: 6px; }
.sb-source-refs img {
@@ -1765,6 +1767,10 @@
onblur="updateName()" onkeydown="if(event.key==='Enter')this.blur()"
style="margin-bottom:8px">
<div id="lbClipDesc" class="sb-status" style="margin-bottom:6px;font-size:11px;color:#555"></div>
<div id="lbGenPromptWrap" style="display:none;margin-bottom:8px">
<div class="sb-label" style="margin-bottom:3px">Generation prompt</div>
<div id="lbGenPrompt" style="font-size:11px;color:#888;line-height:1.4;word-break:break-word"></div>
</div>
<div class="sb-sep"></div>
<div class="sb-label">Order & visibility</div>
<div class="sb-actions" style="margin-bottom:8px">
@@ -1783,8 +1789,10 @@
<div class="sb-actions" style="margin-bottom:8px">
<button class="sb-btn" id="lbExtract" style="display:none" onclick="extractCurrentImage()">Extract</button>
<button class="sb-btn" id="lbNoBgBtn" onclick="lbRemoveBg()">No BG</button>
<button class="sb-btn" id="lbCropBtn" style="display:none" onclick="lbAutoCrop()" title="Crop away transparent border">Crop</button>
<button class="sb-btn" id="lbDuplicateBtn" onclick="lbDuplicate()" title="Duplicate image into same group">Duplicate</button>
<a class="sb-btn" id="lbDownloadBtn" download style="text-decoration:none">Download</a>
<button class="sb-btn danger" onclick="lbDelete()">Delete</button>
<button class="sb-btn danger" id="lbDeleteBtn" onclick="lbDeleteArm()" title="Click once to arm, then again to confirm">Delete</button>
</div>
<div id="lbSourceRefs" class="sb-source-refs" style="display:none"></div>
</div>
@@ -2123,6 +2131,9 @@
let availableVideos = []; // populated from /videos
let _fsActiveTab = 'swap';
let _fsSelectedPoses = new Set();
let _sbPoseEdits = {}; // poseName → edited text
let _sbGenJobId = null;
let _sbGenJobPollTimer= null;
let _fsTrimVideo = null;
function escHtml(s) {
@@ -2177,6 +2188,8 @@
function startGroupCycle(base) {
cycleIdx.set(base, 0); // index into visibleIdx array
const id = setInterval(() => {
// Don't update gallery cards while studio is open — saves GPU and avoids distraction
if (document.getElementById('studio').classList.contains('open')) return;
const data = groupData.get(base);
if (!data || !data.visibleIdx || data.visibleIdx.length < 2) { clearInterval(id); cycleTimers.delete(base); return; }
const card = [...document.querySelectorAll('.image-card')].find(c => c.dataset.group === base);
@@ -2194,6 +2207,8 @@
// --- studio view (replaces lightbox) ---
let lbUrls = [], lbNames = [], lbIdx = 0;
let _activeSidebarTab = localStorage.getItem('studioSidebarTab') || 'info';
// Maps fname → nobg sidecar URL; viewer shows sidecar while this entry exists
const _nobgSidecars = new Map();
function openLightbox(gid, startIdx) { // kept for compat
openStudio(gid, startIdx);
@@ -2209,6 +2224,8 @@
lbIdx = startIdx !== undefined ? startIdx : (cycleIdx.get(gid) || 0);
updateStudio();
document.getElementById('studio').classList.add('open');
// Hide main page scrollbar — nothing in studio scrolls the page
document.body.style.overflow = 'hidden';
// Restore sidebar state
const sidebar = document.getElementById('studioSidebar');
const btn = document.getElementById('sidebarInnerToggle');
@@ -2221,6 +2238,7 @@
function closeStudio() {
document.getElementById('studio').classList.remove('open');
document.body.style.overflow = '';
}
function lbNav(dir) {
@@ -2261,6 +2279,12 @@
const clipEl = document.getElementById('lbClipDesc');
if (clipEl) clipEl.textContent = clipDescriptions[fname] || '';
const genPromptWrap = document.getElementById('lbGenPromptWrap');
const genPromptEl = document.getElementById('lbGenPrompt');
const genPrompt = filePrompts[fname] || '';
if (genPromptWrap) genPromptWrap.style.display = genPrompt ? '' : 'none';
if (genPromptEl) genPromptEl.textContent = genPrompt;
const pose = filePoses[fname];
const poseTag = document.getElementById('lbPoseTag');
if (pose) { poseTag.textContent = '⛷ ' + pose; poseTag.style.display = ''; }
@@ -2278,6 +2302,8 @@
if (noBgBtn) noBgBtn.style.display = (!isVid && fileHasBg[fname] !== false) ? '' : 'none';
if (undressBtn) undressBtn.style.display = (!isVid && fileHasClothing[fname] === true) ? '' : 'none';
if (faceswapBtn)faceswapBtn.style.display = !isVid ? '' : 'none';
const cropBtn = document.getElementById('lbCropBtn');
if (cropBtn) cropBtn.style.display = (!isVid && fileHasBg[fname] === false) ? '' : 'none';
// Source refs
const refs = fileSourceRefs[fname];
@@ -2447,24 +2473,96 @@
}
}
async function lbDelete() {
// Two-step inline confirmation: first click arms the button, second confirms.
let _deleteArmed = false, _deleteArmTimer = null;
function lbDeleteArm() {
const btn = document.getElementById('lbDeleteBtn');
if (!btn) return;
if (_deleteArmed) { lbDeleteConfirm(); return; }
_deleteArmed = true;
btn.textContent = 'Confirm delete';
btn.style.background = '#dc2626';
clearTimeout(_deleteArmTimer);
_deleteArmTimer = setTimeout(() => {
_deleteArmed = false;
if (btn) { btn.textContent = 'Delete'; btn.style.background = ''; }
}, 3500);
}
async function lbDeleteConfirm() {
_deleteArmed = false;
clearTimeout(_deleteArmTimer);
const btn = document.getElementById('lbDeleteBtn');
if (btn) { btn.textContent = 'Delete'; btn.style.background = ''; btn.disabled = true; }
const fname = lbNames[lbIdx];
if (!confirm(`Are you sure you want to delete this image? (${fname})`)) return;
try {
const r = await fetch(`${API}/images/${fname}`, { method: 'DELETE' });
if (r.ok) {
showToast(`Deleted ${fname}`, 'success');
closeLightbox();
refreshNow();
showToast(`Deleted`, 'success');
if (btn) btn.disabled = false;
// Remove from current group view
lbUrls.splice(lbIdx, 1);
lbNames.splice(lbIdx, 1);
if (lbNames.length === 0) {
closeStudio();
refreshNow();
} else {
lbIdx = Math.min(lbIdx, lbNames.length - 1);
updateStudio();
refreshNow();
}
} else {
showToast(`Failed to delete ${fname}`, 'error');
showToast(`Failed to delete`, 'error');
if (btn) btn.disabled = false;
}
} catch (e) {
showToast(`Failed to delete: ${e}`, 'error');
if (btn) btn.disabled = false;
}
}
async function lbAutoCrop() {
const fname = lbNames[lbIdx];
if (!fname) return;
const btn = document.getElementById('lbCropBtn');
if (btn) { btn.disabled = true; btn.textContent = 'Cropping…'; }
try {
const r = await fetch(`${API}/images/${encodeURIComponent(fname)}/autocrop`, { method: 'POST' });
if (r.ok) {
showToast('Cropped', 'success');
lbUrls[lbIdx] = IMAGE_FOLDER + fname + '?t=' + Date.now();
updateStudio();
} else {
showToast('Crop failed: ' + await r.text(), 'error');
}
} catch (e) { showToast('Crop failed: ' + e, 'error'); }
if (btn) { btn.disabled = false; btn.textContent = 'Crop'; }
}
async function lbDuplicate() {
const fname = lbNames[lbIdx];
if (!fname) return;
const btn = document.getElementById('lbDuplicateBtn');
if (btn) btn.disabled = true;
showToast('Duplicating…');
try {
const r = await fetch(`${API}/images/${encodeURIComponent(fname)}/duplicate`, { method: 'POST' });
if (r.ok) {
const d = await r.json();
showToast('Duplicated', 'success');
// Insert the duplicate right after the current image in the studio strip
lbUrls.splice(lbIdx + 1, 0, IMAGE_FOLDER + d.new_filename + '?t=' + Date.now());
lbNames.splice(lbIdx + 1, 0, d.new_filename);
lbIdx = lbIdx + 1;
updateStudio();
refreshNow();
} else {
showToast('Duplicate failed', 'error');
}
} catch (e) { showToast('Duplicate failed: ' + e, 'error'); }
if (btn) btn.disabled = false;
}
async function lbRemoveBg() {
const fname = lbNames[lbIdx];
showToast(`Removing background for ${fname}...`);
@@ -3455,7 +3553,13 @@
function renderSidebarGenerate() {
const panel = document.getElementById('sbPanelGenerate');
if (!panel) return;
// Use lbNames (current open group) to find already-generated poses
// Preserve live input values before re-render
const prevPromptVal = document.getElementById('sbGenPromptInput')?.value ?? '';
_fsSelectedPoses.forEach(name => {
const el = document.getElementById('sbPoseEdit_' + CSS.escape(name));
if (el) _sbPoseEdits[name] = el.value;
});
const donePoses = new Set();
lbNames.forEach(n => { if (filePoses[n]) donePoses.add(filePoses[n]); });
@@ -3473,21 +3577,44 @@
return `<button class="${cls}" onclick="toggleSbPose('${nSafe}')" title="${tip}">${escHtml(name)}</button>`;
}).join('');
}
html += `</div>
<div class="sb-sep"></div>
html += `</div>`;
// Fine-tune section: one editable textarea per selected pose
if (_fsSelectedPoses.size > 0) {
html += `<div class="sb-sep"></div><div class="sb-label">Fine-tune poses</div>`;
_fsSelectedPoses.forEach(name => {
const origText = String(availablePoses[name]?.text ?? availablePoses[name] ?? name);
const curText = (_sbPoseEdits[name] !== undefined) ? _sbPoseEdits[name] : origText;
const idSafe = escHtml(name).replace(/"/g, '&quot;');
html += `<div style="font-size:11px;color:#888;margin-bottom:3px">${escHtml(name)}</div>
<textarea id="sbPoseEdit_${idSafe}"
style="width:100%;box-sizing:border-box;background:#111;border:1px solid #2a2a2a;border-radius:5px;color:#ccc;font-size:11px;padding:6px;resize:vertical;min-height:60px;margin-bottom:6px"
oninput="sbSavePoseEdit('${name.replace(/'/g,"\\'")}')">${escHtml(curText)}</textarea>`;
});
}
html += `<div class="sb-sep"></div>
<div class="sb-label">Custom prompt</div>
<input type="text" class="sb-input" id="sbGenPromptInput"
placeholder="Prompt — overrides pose" oninput="updateSbGenBtn()" style="margin-bottom:10px">
<div style="display:flex;align-items:center;gap:8px">
<span id="sbGenJobStatus" style="flex:1;font-size:11px;color:#888;display:none">
list="promptHistory"
placeholder="Prompt — overrides pose" oninput="updateSbGenBtn()" style="margin-bottom:10px"
value="${escHtml(prevPromptVal)}">
<div style="display:flex;align-items:center;gap:8px;flex-wrap:wrap">
<span id="sbGenJobStatus" style="flex:1;font-size:11px;color:#888;display:none;min-width:120px">
<span class="sb-spinner"></span><span id="sbGenJobText">Generating…</span>
</span>
<button class="sb-btn danger" id="sbCancelBtn" style="display:none" onclick="cancelSbGenerate()">Cancel</button>
<button class="sb-btn primary" id="sbGenBtn" onclick="submitSbGenerate()" disabled>Generate</button>
</div>`;
panel.innerHTML = html;
updateSbGenBtn();
}
function sbSavePoseEdit(name) {
const el = document.getElementById('sbPoseEdit_' + CSS.escape(name));
if (el) _sbPoseEdits[name] = el.value;
}
function toggleSbPose(name) {
if (_fsSelectedPoses.has(name)) _fsSelectedPoses.delete(name);
else _fsSelectedPoses.add(name);
@@ -3503,21 +3630,43 @@
btn.textContent = n > 1 ? `Generate (${n})` : 'Generate';
}
async function cancelSbGenerate() {
if (!_sbGenJobId) return;
const cancelBtn = document.getElementById('sbCancelBtn');
if (cancelBtn) cancelBtn.disabled = true;
try {
await fetch(`${API}/batch/${_sbGenJobId}`, { method: 'DELETE' });
showToast('Generation cancelled', 'info');
} catch (_) {}
clearTimeout(_sbGenJobPollTimer);
_sbGenJobId = null;
const btn = document.getElementById('sbGenBtn');
const statusEl = document.getElementById('sbGenJobStatus');
if (btn) { btn.disabled = false; btn.textContent = 'Generate'; }
if (cancelBtn) { cancelBtn.disabled = false; cancelBtn.style.display = 'none'; }
if (statusEl) statusEl.style.display = 'none';
}
async function submitSbGenerate() {
if (!_fsModelFilename) return;
const promptVal = (document.getElementById('sbGenPromptInput')?.value || '').trim();
const prompts = [], poses = [];
_fsSelectedPoses.forEach(name => {
poses.push(name);
prompts.push(availablePoses[name]?.text ?? availablePoses[name] ?? name);
// Use edited text if available, else original
const edited = _sbPoseEdits[name];
const orig = availablePoses[name]?.text ?? availablePoses[name] ?? name;
prompts.push((edited !== undefined && edited.trim()) ? edited.trim() : String(orig));
});
if (promptVal) { prompts.push(promptVal); poses.push(null); }
if (promptVal) { prompts.push(promptVal); poses.push(null); savePromptHistory(promptVal); }
if (prompts.length === 0) return;
const btn = document.getElementById('sbGenBtn');
btn.disabled = true; btn.textContent = 'Submitting…';
const statusEl = document.getElementById('sbGenJobStatus');
const textEl = document.getElementById('sbGenJobText');
const statusEl = document.getElementById('sbGenJobStatus');
const textEl = document.getElementById('sbGenJobText');
const cancelBtn = document.getElementById('sbCancelBtn');
statusEl.style.display = 'inline-flex';
if (cancelBtn) cancelBtn.style.display = '';
textEl.textContent = `Queuing ${prompts.length} task(s)…`;
try {
const r = await fetch(`${API}/batch`, {
@@ -3530,37 +3679,59 @@
});
if (!r.ok) {
textEl.textContent = `Error: ${await r.text()}`;
btn.disabled = false; btn.textContent = 'Retry'; return;
btn.disabled = false; btn.textContent = 'Retry';
if (cancelBtn) cancelBtn.style.display = 'none';
return;
}
const { job_id, total } = await r.json();
_sbGenJobId = job_id;
showToast(`Generating ${total} image${total !== 1 ? 's' : ''}`, 'info');
textEl.textContent = `Generating… 0/${total}`;
let prevDone = 0;
const pollGen = () => {
clearTimeout(_fsJobPollTimer);
_fsJobPollTimer = setTimeout(async () => {
clearTimeout(_sbGenJobPollTimer);
_sbGenJobPollTimer = setTimeout(async () => {
try {
const jr = await fetch(`${API}/batch/${job_id}`);
if (!jr.ok) { pollGen(); return; }
const job = await jr.json();
textEl.textContent = `Generating… ${job.done + job.failed}/${total}`;
const finished = job.done + job.failed;
textEl.textContent = `Generating… ${finished}/${total}`;
// Refresh UI as each task completes
if (job.done > prevDone) { prevDone = job.done; refreshNow(); }
if (job.status === 'running') { pollGen(); return; }
if (job.status === 'cancelled') {
statusEl.style.display = 'none';
if (cancelBtn) cancelBtn.style.display = 'none';
btn.disabled = false; btn.textContent = 'Generate';
_sbGenJobId = null;
return;
}
if (job.status === 'done') {
showToast('Generation complete!', 'success');
statusEl.style.display = 'none';
if (cancelBtn) cancelBtn.style.display = 'none';
btn.disabled = false; btn.textContent = 'Generate';
_fsSelectedPoses.clear();
_sbPoseEdits = {};
_sbGenJobId = null;
refreshNow();
renderSidebarGenerate();
} else {
textEl.textContent = `Error: ${job.error || 'unknown'}`;
btn.disabled = false; btn.textContent = 'Retry';
if (cancelBtn) cancelBtn.style.display = 'none';
_sbGenJobId = null;
}
} catch (e) { pollGen(); }
}, 2500);
}, 2000);
};
pollGen();
} catch (e) {
textEl.textContent = `API error: ${e}`;
btn.disabled = false; btn.textContent = 'Retry';
if (cancelBtn) cancelBtn.style.display = 'none';
_sbGenJobId = null;
}
}
@@ -3632,8 +3803,9 @@
const stem = v.replace(/\.[^.]+$/, '');
const vSafe = v.replace(/'/g, "\\'");
const sel = _fsSelectedVideo === v ? ' selected' : '';
html += `<div class="sb-template-card${sel}" onclick="sbSelectTemplate('${vSafe}')">
<video src="${API}/wireframe/${encodeURIComponent(v)}" muted loop autoplay playsinline
html += `<div class="sb-template-card${sel}" onclick="sbSelectTemplate('${vSafe}')"
onmouseenter="this.querySelector('video').play()" onmouseleave="this.querySelector('video').pause()">
<video src="${API}/wireframe/${encodeURIComponent(v)}" muted loop playsinline
preload="metadata" style="pointer-events:none;width:100%;height:100%;object-fit:cover"></video>
<div class="sb-template-label">${escHtml(stem)}</div>
<button class="sb-template-trim-btn" title="Trim video"
@@ -3865,8 +4037,9 @@
const stem = v.replace(/\.[^.]+$/, '');
const vSafe = v.replace(/'/g, "\\'");
const sel = _sceneVideo === v ? ' selected' : '';
html += `<div class="sb-template-card${sel}" onclick="sceneSelectVideo('${vSafe}')">
<video src="${API}/wireframe/${encodeURIComponent(v)}" muted loop autoplay playsinline
html += `<div class="sb-template-card${sel}" onclick="sceneSelectVideo('${vSafe}')"
onmouseenter="this.querySelector('video').play()" onmouseleave="this.querySelector('video').pause()">
<video src="${API}/wireframe/${encodeURIComponent(v)}" muted loop playsinline
preload="metadata" style="pointer-events:none;width:100%;height:100%;object-fit:cover"></video>
<div class="sb-template-label">${escHtml(stem)}</div>
</div>`;
@@ -4092,8 +4265,9 @@
if (!panel) return;
panel.innerHTML = `
<div style="font-size:11px;color:#666;margin-bottom:12px;line-height:1.6">
Remove the background using SAM2 (when available) or rembg fallback.
The result is a transparent PNG. Restore BG composites alpha back to white.
Remove background using SAM2 or rembg fallback. The original file is
kept intact — a sidecar <code>.nobg.png</code> is created. Restore BG
simply shows the original again without any file change.
</div>
<div style="display:flex;gap:8px;margin-bottom:8px;flex-wrap:wrap">
<button class="sb-btn" id="sbSam2Btn" onclick="sam2RemoveBg()">Remove BG</button>
@@ -4106,7 +4280,7 @@
<span>Checkerboard (show transparency)</span>
</label>
<div style="font-size:10px;color:#555;line-height:1.4">
SAM2 segments the largest foreground subject.<br>
SAM2 merges all non-border masks (preserves hair, glasses, sandals).<br>
Requires sam2_checkpoint in config.json.
</div>`;
// Check SAM2 availability
@@ -4129,34 +4303,40 @@
if (statusEl) statusEl.textContent = 'Error: ' + await r.text();
} else {
const d = await r.json();
if (statusEl) statusEl.textContent = d.used_sam2 ? 'Done (SAM2)' : 'Done (rembg)';
const label = d.used_sam2 ? 'Done (SAM2)' : 'Done (rembg)';
if (statusEl) statusEl.textContent = label;
showToast('Background removed', 'success');
const img = document.getElementById('lbImg');
if (img) { img.src = img.src.split('?')[0] + '?t=' + Date.now(); }
// Build URL same way as all gallery images: IMAGE_FOLDER + filename
const nobgUrl = IMAGE_FOLDER + d.nobg_filename + '?t=' + Date.now();
_nobgSidecars.set(fname, nobgUrl);
// Preload before swap to avoid black flash
const preload = new Image();
preload.onload = () => {
const img = document.getElementById('lbImg');
if (img) img.src = nobgUrl;
const cb = document.getElementById('sbCheckerboard');
if (cb && !cb.checked) { cb.checked = true; toggleCheckerboard(true); }
};
preload.src = nobgUrl;
}
} catch (e) { if (statusEl) statusEl.textContent = 'Error: ' + e; }
if (btn) btn.disabled = false;
}
async function restoreBg() {
function restoreBg() {
// Non-destructive: just revert the viewer to the original URL.
// The sidecar .nobg.png stays on disk for future use.
const fname = lbNames[lbIdx];
if (!fname) return;
const btn = document.getElementById('sbRestoreBgBtn');
_nobgSidecars.delete(fname);
const img = document.getElementById('lbImg');
if (img) img.src = lbUrls[lbIdx] + (lbUrls[lbIdx].includes('?') ? '&' : '?') + 't=' + Date.now();
const statusEl = document.getElementById('sbSegStatus');
if (btn) btn.disabled = true;
if (statusEl) statusEl.textContent = 'Restoring…';
try {
const r = await fetch(`${API}/restore-background/${encodeURIComponent(fname)}`, { method: 'POST' });
if (!r.ok) {
if (statusEl) statusEl.textContent = 'Error: ' + await r.text();
} else {
if (statusEl) statusEl.textContent = 'Background restored';
showToast('Background restored', 'success');
const img = document.getElementById('lbImg');
if (img) { img.src = img.src.split('?')[0] + '?t=' + Date.now(); }
}
} catch (e) { if (statusEl) statusEl.textContent = 'Error: ' + e; }
if (btn) btn.disabled = false;
if (statusEl) statusEl.textContent = 'Original restored';
// Turn off checkerboard
const cb = document.getElementById('sbCheckerboard');
if (cb && cb.checked) { cb.checked = false; toggleCheckerboard(false); }
showToast('Original image shown', 'success');
}
function toggleCheckerboard(on) {

View File

@@ -2,9 +2,9 @@
"api_url": "http://127.0.0.1:8500/edit",
"prompt": "high quality. realistic. detailed, female nude. realistic, high quality. realistic. detailed. female nude. realistic",
"base_prompts": [
"Head-on a full-body three-quarter full-nude-body female portrait, realistic, transparent background",
"Head-on straight-on full-nude-body female portrait, realistic, transparent background",
"Head-on straight-on full-body female portrait, realistic, no background",
"Head-on full-nude-body three-quarter female portrait, realistic, transparent background",
"Head-on straight-on full-nude-body female portrait, realistic, transparent background",
"Head-on straight-on full-body female portrait, realistic, no background",
"high quality, full-nude-body, female, masterpiece, realistic, photo, looking at viewer",
"high quality, full-nude-body, female, masterpiece, realistic, photo, detailed skin, professional lighting, transparent background",
"high quality, full-nude-body, female, masterpiece, realistic, photo, cinematic lighting, dramatic shadows, sharp focus, transparent background"

View File

@@ -647,7 +647,7 @@ def _faceswap_worker_ff(job_id: str, model_filename: str, video_name: str,
'--execution-providers', 'cuda',
# Limit to 2 threads: each thread owns a cuBLAS handle + workspace; more
# threads exhausts VRAM when ComfyUI is running concurrently on the same GPU.
#'--execution-thread-count', '2',
'--execution-thread-count', '2',
'--face-swapper-model', 'ghost_3_256',
# The default yolo_face detector at score 0.5 misses the extreme-angle /
# cropped close-up faces common in these POV template clips, so the swap
@@ -894,6 +894,8 @@ def _batch_worker(job_id: str, filenames: list, prompts: list[str], poses: list,
try:
base_pil = Image.open(fpath).convert("RGB")
for prompt, pose in zip(prompts, poses):
if jobs[job_id].get("cancelled"):
return
try:
pil = base_pil
# Rotate 180° for poses that work better upside-down
@@ -1057,7 +1059,7 @@ def start_batch(req: BatchRequest):
total_tasks = len(req.filenames) * len(prompts)
job_id = uuid.uuid4().hex[:8]
jobs[job_id] = {"status": "running", "total": total_tasks, "done": 0, "failed": 0}
jobs[job_id] = {"status": "running", "total": total_tasks, "done": 0, "failed": 0, "cancelled": False}
t = threading.Thread(
target=_batch_worker,
args=(job_id, req.filenames, prompts, poses, req.seed, req.max_area, req.group_id),
@@ -1067,6 +1069,15 @@ def start_batch(req: BatchRequest):
return {"job_id": job_id, "total": total_tasks}
@app.delete("/batch/{job_id}")
def cancel_batch(job_id: str):
if job_id not in jobs:
raise HTTPException(404, "Job not found")
jobs[job_id]["cancelled"] = True
jobs[job_id]["status"] = "cancelled"
return {"status": "cancelled", "job_id": job_id}
class MultiRefRequest(BaseModel):
filenames: list[str] # 23 reference images; first is primary (image1)
prompt: str | list[str]
@@ -1914,12 +1925,14 @@ def _load_sam2():
def _apply_transparency_sam2(png_bytes: bytes) -> bytes:
"""Remove background with SAM2, point-prompted on the central subject; fallback to rembg.
"""Remove background with SAM2 bbox-based segmentation; fallback to rembg.
Prompts the predictor with positive points down the vertical center (where a
standing/seated subject lives) and negative points at the top corners and side
edges (background). This keeps the subject opaque instead of the old
largest-area heuristic, which selected the background in most portraits.
Mimics the reference approach (bbox → SAM2) but without an external
detector: we pass a generous bbox covering the central subject area.
For portraits/full-body shots the subject fills most of the frame, so a
5 % margin bbox reliably captures hair, glasses, and sandals without the
point-prompt clipping issues. multimask_output=True lets SAM2 propose
three masks; we pick the highest-scoring one.
"""
predictor = _load_sam2()
if predictor is False:
@@ -1930,27 +1943,19 @@ def _apply_transparency_sam2(png_bytes: bytes) -> bytes:
img = Image.open(io.BytesIO(png_bytes)).convert("RGB")
arr = np.array(img)
h, w = arr.shape[:2]
point_coords = np.array([
[w * 0.50, h * 0.30], # subject (upper center)
[w * 0.50, h * 0.50], # subject (center)
[w * 0.50, h * 0.70], # subject (lower center)
[w * 0.04, h * 0.06], # background (top-left)
[w * 0.96, h * 0.06], # background (top-right)
[w * 0.03, h * 0.50], # background (mid-left edge)
[w * 0.97, h * 0.50], # background (mid-right edge)
], dtype=np.float32)
point_labels = np.array([1, 1, 1, 0, 0, 0, 0], dtype=np.int32)
# Generous bbox — 5 % margin H, 2 % margin V — covers the whole subject
box = np.array([[int(w * 0.05), int(h * 0.02),
int(w * 0.95), int(h * 0.98)]], dtype=np.float32)
with torch.inference_mode():
predictor.set_image(arr)
masks, scores, _ = predictor.predict(
point_coords=point_coords,
point_labels=point_labels,
box=box,
multimask_output=True,
)
if masks is None or len(masks) == 0:
return _apply_transparency(png_bytes)
best = masks[int(np.argmax(scores))]
mask_np = (best.astype(np.uint8) * 255)
mask_np = best.astype(np.uint8) * 255
rgba = img.convert("RGBA")
r, g, b, _ = rgba.split()
alpha = Image.fromarray(mask_np, mode="L")
@@ -1965,18 +1970,84 @@ def _apply_transparency_sam2(png_bytes: bytes) -> bytes:
@app.post("/remove-background-sam/{filename}")
def remove_background_sam(filename: str):
"""SAM2-based background removal (RGBA PNG). Falls back to rembg if SAM2 unavailable."""
"""SAM2-based background removal.
Writes the transparent result as a sidecar <stem>.nobg.png alongside the
original, which is left untouched. Returns the sidecar URL so the UI can
switch the viewer without touching the source file.
Falls back to rembg when SAM2 is unavailable.
"""
person = database.get_person(filename)
if not person or not person[5] or not os.path.exists(person[5]):
raise HTTPException(404, "Image file not found")
path = person[5]
output_dir = os.path.dirname(path)
stem = os.path.splitext(filename)[0]
nobg_filename = f"{stem}.nobg.png"
nobg_path = os.path.join(output_dir, nobg_filename)
with open(path, "rb") as f:
png_bytes = f.read()
transparent_png = _apply_transparency_sam2(png_bytes)
with open(path, "wb") as f:
with open(nobg_path, "wb") as f:
f.write(transparent_png)
# Register sidecar in DB so it appears in the same group
group_id = person[1]
database.upsert_person(nobg_filename, filepath=nobg_path,
group_id=group_id, has_background=False)
used_sam2 = _sam2_predictor is not False and _sam2_predictor is not None
return {"status": "success", "filename": filename, "used_sam2": used_sam2}
return {
"status": "success",
"filename": filename,
"nobg_filename": nobg_filename,
"nobg_url": f"/output/{nobg_filename}",
"used_sam2": used_sam2,
}
@app.post("/images/{filename}/autocrop")
def autocrop_image(filename: str):
"""Crop away transparent borders from an image in-place."""
import numpy as np
person = database.get_person(filename)
if not person or not person[5] or not os.path.exists(person[5]):
raise HTTPException(404, "Image file not found")
path = person[5]
img = Image.open(path).convert("RGBA")
arr = np.array(img)
alpha = arr[:, :, 3]
rows = np.any(alpha > 0, axis=1)
cols = np.any(alpha > 0, axis=0)
if not rows.any():
raise HTTPException(400, "Image is fully transparent")
rmin, rmax = np.where(rows)[0][[0, -1]]
cmin, cmax = np.where(cols)[0][[0, -1]]
cropped = img.crop((cmin, rmin, cmax + 1, rmax + 1))
cropped.save(path, format="PNG")
return {"status": "success", "filename": filename, "box": [int(cmin), int(rmin), int(cmax+1), int(rmax+1)]}
@app.post("/images/{filename}/duplicate")
def duplicate_image(filename: str):
"""Copy an image into the same group with a fresh timestamp-based filename."""
import shutil as _shutil
from datetime import datetime as _dt
person = database.get_person(filename)
if not person or not person[5] or not os.path.exists(person[5]):
raise HTTPException(404, "Image file not found")
path = person[5]
output_dir = os.path.dirname(path)
ext = os.path.splitext(filename)[1] or ".png"
ts = _dt.now().strftime("%Y%m%d_%H%M%S")
stem = os.path.splitext(filename)[0]
new_filename = f"{ts}_dup_{stem}{ext}"
new_path = os.path.join(output_dir, new_filename)
_shutil.copy2(path, new_path)
group_id = person[1]
database.upsert_person(new_filename, filepath=new_path, group_id=group_id)
return {"status": "success", "new_filename": new_filename, "new_url": f"/output/{new_filename}"}
@app.post("/restore-background/{filename}")

1319
tour-comfy/new-poses.md Normal file

File diff suppressed because it is too large Load Diff

View File

@@ -42,16 +42,24 @@ Lying flat on her back, bending one leg and bringing it up to the chest, the oth
Place one arm under your head, and the other arm stretched out to the side.
Capture the curves and smooth lines of the body, focusing on the subtle curves of the back and the stretch of the bent leg.
Head on top.
Realistic, anatomically precise
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The draak (beta):
Lie on your back with your arms stretched out to the sides.
Looking into the camera.
Bring your legs up to your chest, slightly lift for invitation, and cross one leg over the other.
Lean up to balance on your elbows, showcasing the extended arms and strong legs.
Realistic, anatomically precise
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Butterfly:
# The Butterfly (Closed):
lying flat on back in reclined butterfly pose.
soles of feet pressed together, knees bent and falling open outward to sides, hips fully open.
hands clasped around the legs, pulling the feet up toward the chest.
legs crossed at the shins or ankles, one leg resting over the other.
head resting on top, looking directly into camera. Serene, open.
Perfect anatomy, realistic
# The Butterfly (Open):
Lying flat on her back in a reclined butterfly pose.
Soles of feet pressed firmly together, knees relaxed and falling open outward to the sides, hips fully open.
Arms resting loosely overhead or at her sides.
@@ -70,14 +78,14 @@ Lie on your side with your upper arm behind your head and your lower arm stretch
The upper leg bent, while the lower leg is straight.
Lean slightly into the pose, showcasing the straight line of the lower leg and the bent upper leg.
Highlight the soft, supple curves of the torso and hips.
Realistic, anatomically precise
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Backbend:
Lie on your back with your knees bent and your feet touching.
Lift your feet off the ground and arch your back.
Look towards the ceiling with a seductive expression, showcasing the arched back and exposed legs.
Focus on the graceful lines of the body and the tension in the back and legs.
Realistic, anatomically precise
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Lotus:
Lie on your back with your knees bent and your feet touching.
@@ -115,7 +123,7 @@ Bring your legs up to your chest and cross them.
Clasp your hands around your feet and pull your legs towards your chest.
Lean slightly into the pose, showcasing the cross-legged position and the symmetry of the pose.
Highlight the smooth curves of the body and the intricate pose.
Realistic, perfect anatomy
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Celestial (beta):
Looking into the camera with strong eye contact and a serene, confident expression.
@@ -123,7 +131,7 @@ Lie on your back with your arms stretched out to the sides.
Bring your legs up to your chest and cross them.
Bend your knees and clasp your hands around your feet.
Lean back slightly into the pose, showcasing the bend in the knees and the clasp around the feet.
Realistic, perfect anatomy
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Offering:
kneeling upright, sitting back on heels.
@@ -140,16 +148,8 @@ bottom leg extended straight, toes pointed.
top arm resting on bent knee or reaching overhead.
torso twisted slightly toward camera, hips stacked.
Looking directly into camera. Relaxed, composed.
Realistic, anatomically precise.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Ascension:
lying on back.
arms extended overhead, hands clasped or reaching past the head.
legs lifted straight up together, fully extended toward ceiling.
lower back pressed flat to the ground, shoulders relaxed.
vertical line from shoulders through heels.
Looking directly into camera. Weightless, transcendent.
Perfect anatomy, realistic
# The Bridge:
lying on back, feet flat on ground, knees bent.
@@ -239,14 +239,6 @@ head lowered, face turned down toward the ground, chin tucked.
Looking down, not at camera. Contemplative, submissive.
Perfect anatomy, realistic
# The Garter:
seated on the edge of a surface, legs slightly parted.
hands at the thighs, fingers hooking into the top of thigh-high stockings or garter straps.
torso leaning forward slightly, shoulders rolled back, chest presented.
head tilted, lips parted.
Looking directly into camera. Teasing, anticipatory.
Perfect anatomy, realistic
# The Unclasp:
standing, back partially turned toward camera over one shoulder.
arms reaching behind, hands at the back working to unhook a bra clasp.
@@ -599,15 +591,6 @@ body forming a wide, open V-shape.
Looking directly into camera. Open, radiant.
Perfect anatomy, realistic
# The Sickle (beta):
lying on back, legs lifted and bent.
knees drawing toward the chest, then extending and lowering toward the head.
feet arched, toes pointing toward the ground behind the head.
arms wrapped around the thighs or extended to the sides.
body folded tightly, spine compressed.
Looking at the knees, then into camera. Curved, hooked.
Perfect anatomy, realistic
# The Lantern:
kneeling, knees apart, sitting back on the heels.
torso upright, spine long.
@@ -641,8 +624,8 @@ torso lifted in a backbend, chest and shoulders arching upward.
head thrown back, neck stretched.
legs remain on the ground, feet pointed.
body forming a gentle, upward curve from hips to head.
Looking upward, not at camera. Trembling, stretched.
Perfect anatomy, realistic
Looking upward, not at camera. Stretched body.
Perfect anatomy, hyperrealistic
# The Loom:
seated, legs extended straight forward, feet flexed.
@@ -707,19 +690,679 @@ head lifted, looking at the toes.
Looking at the toes, then into camera. Suspended, horizontal.
Perfect anatomy, realistic
# The Sling:
lying on back, one knee drawn to the chest.
arm of the same side reaching through the gap between the legs to grasp the shin or ankle.
other leg extended straight along the ground.
other arm extended to the side.
head turned toward the bent knee.
Looking at the knee, then into camera. Held, supported.
Perfect anatomy, realistic
# The Vault:
standing, legs apart, arms extended overhead.
torso arched backward deeply, hips pushed forward.
chest open to the sky, head hanging back.
body forming a deep, continuous arch from fingertips to heels.
Looking upward, not at camera. Arched, soaring.
Perfect anatomy, realistic
Perfect anatomy, realistic
---
# The Pulse:
lying on back, knees bent and parted, feet flat on the ground.
one hand resting on the lower abdomen, fingers spread, pressing gently.
other arm extended to the side, palm up.
hips slightly lifted, pelvis tilted.
head turned to the side, lips parted.
Looking directly into camera. Aware, internal.
Perfect anatomy, realistic
---
# The Trace:
standing, one hand at the collarbone, fingers trailing slowly down the sternum.
other hand resting on the hip.
head tilted back, eyes half-closed.
weight on one leg, opposite knee slightly bent.
Looking upward, then into camera. Sensation, discovery.
Perfect anatomy, realistic
---
# The Splay:
lying on back, legs spread wide, knees bent, feet flat on the ground.
arms extended overhead, hands clasping the wrists.
torso arched slightly, chest lifted.
head tilted back, throat exposed.
Looking directly into camera. Open, offered.
Perfect anatomy, realistic
---
# The Clutch:
seated, legs tucked under, sitting back on the heels.
arms wrapped around the body, one hand at the breast, the other at the hip.
head tilted down, chin near the chest.
shoulders rounded, body curled inward.
Looking up into camera. Self-held, protective.
Perfect anatomy, realistic
---
# The Drift:
lying on side, bottom leg extended straight.
top leg bent and drawn forward, knee resting near the chest.
top hand resting on the inner thigh, fingers trailing toward the knee.
bottom arm extended under the head.
head resting on the arm, gaze soft.
Looking directly into camera. Drifting, languid.
Perfect anatomy, realistic
---
# The Arch:
lying on back, arms extended overhead along the ground.
legs lifted and bent, knees drawing toward the chest.
feet crossed at the ankles, toes pointed.
lower back pressed flat, hips lifted slightly.
head turned to the side, cheek on the ground.
Looking directly into camera. Curved, lifted.
Perfect anatomy, realistic
---
# The Press:
standing against a wall, back flat, one leg bent with foot planted against the wall.
arms extended overhead, palms flat against the wall.
other leg straight, weight on the heel.
head tilted back, neck stretched.
Looking upward, then into camera. Pinned, pressed.
Perfect anatomy, realistic
---
# The Gather:
lying on stomach, arms at the sides.
legs bent, knees drawing up toward the chest.
arms reaching back, hands clasping the lower back or buttocks.
hips lifted, lower back arched.
head turned to the side, cheek on the shoulder.
Looking directly into camera. Gathered, held.
Perfect anatomy, realistic
---
# The Part:
lying on back, legs lifted and spread wide, knees bent.
arms reaching down to grasp the inner thighs or behind the knees.
hips lifted off the ground, pelvis tilted upward.
head lifted, looking down the body toward the camera.
Looking directly into camera. Parted, exposed.
Perfect anatomy, realistic
---
# The Circle:
standing, one leg lifted and bent, foot pressed against the opposite inner thigh.
arms extended to the sides, palms open.
torso twisted, one shoulder forward, one back.
head turned to look over the forward shoulder.
Looking back into camera. Balanced, rotating.
Perfect anatomy, realistic
---
# The Drip:
standing, legs apart, torso folded forward at the hips.
arms hanging loose toward the ground, fingers trailing.
head down, hair cascading toward the floor.
weight on the balls of the feet, heels slightly lifted.
Looking down, then up into camera through the hair. Inverted, dripping.
Perfect anatomy, realistic
---
# The Clasp:
lying on back, knees bent, feet flat on the ground.
arms reaching down between the legs, hands clasped behind the thighs.
hips lifted, lower back arched.
head tilted back, chin toward the chest.
Looking directly into camera. Clasped, lifted.
Perfect anatomy, realistic
---
# The Sigh:
seated, legs extended forward, feet flexed.
torso leaning back, supported on the hands.
legs parted slightly, knees relaxed.
head tilted back, eyes closed, lips parted in exhale.
Looking upward, not at camera. Released, breathless.
Perfect anatomy, realistic
---
# The Tension:
standing, legs apart, arms extended overhead.
hands clasped, arms pulling in opposite directions as if stretching.
torso elongated, ribs visible, abdomen taut.
head tilted back, neck stretched.
Looking upward, not at camera. Stretched, taut.
Perfect anatomy, realistic
---
# The Pool:
lying on back, arms extended to the sides, palms up.
legs spread wide, knees bent, feet flat on the ground.
hips relaxed, pelvis settled.
head turned to one side, cheek on the ground.
Looking directly into camera. Spread, pooled.
Perfect anatomy, realistic
---
# The Knot:
seated, legs crossed tightly, feet tucked under opposite thighs.
arms wrapped around the body, hands clasping opposite shoulders.
head resting on one shoulder, chin tucked.
body compressed into a tight, knotted ball.
Looking directly into camera. Tied, compressed.
Perfect anatomy, realistic
---
# The Reach:
standing, one leg extended forward, foot pointed.
arms extended forward, hands reaching toward the extended foot.
torso folded over the front leg, back flat.
head aligned with the spine, gaze at the toes.
Looking at the toes, then into camera. Extended, reaching.
Perfect anatomy, realistic
---
# The Waver:
standing, legs together, arms extended overhead.
torso swaying to one side, creating a C-curve.
hips pushed to the opposite side, weight on one leg.
head tilted, following the line of the sway.
Looking directly into camera. Swaying, wavering.
Perfect anatomy, realistic
---
# The Hollow:
lying on back, arms extended overhead along the ground.
legs lifted straight up, fully extended.
lower back pressed flat, abdomen hollowed, ribs visible.
shoulders relaxed, neck long.
Looking directly into camera. Hollow, suspended.
Perfect anatomy, realistic
---
# The Garter (Refined):
seated on the edge of a surface, legs slightly parted.
right hand at the right thigh, fingers hooking into the top of a thigh-high stocking or garter strap.
left hand resting on the left knee, palm down.
torso leaning forward slightly, shoulders rolled back, chest presented.
head tilted, lips parted.
Looking directly into camera. Teasing, anticipatory.
Perfect anatomy, realistic, trying on erotic lingerie
---
# The Sling (Refined):
lying on back, right knee drawn to the chest.
right arm reaching between the legs to grasp the right shin.
left leg extended straight along the ground.
left arm extended to the side, palm up.
head turned toward the right knee.
Looking at the knee, then into camera. Held, supported.
Perfect anatomy, realistic
---
# The Sickle (Refined):
lying on back, legs lifted overhead.
legs bent at the knees, then extending and lowering toward the ground behind the head.
feet arched, toes pointing toward the ground behind the head.
arms resting on the ground at the sides, palms down.
body folded tightly, spine compressed.
Looking at the knees, then into camera. Curved, hooked.
Perfect anatomy, realistic
---
# The Bite:
close-up portrait, head and shoulders only.
lower lip caught between the teeth, biting gently.
eyes half-lidded, gaze fixed directly into camera.
head tilted slightly to one side, hair falling across one cheek.
neck elongated, collarbones visible.
Looking directly into camera. Hungry, restrained.
Perfect anatomy, realistic
---
# The Sigh (Facial):
close-up portrait, head tilted back, chin lifted.
eyes closed, lips parted in a soft exhale.
cheeks flushed, breath visible as a faint mist.
head resting against an implied surface behind.
Looking upward, not at camera. Released, breathless.
Perfect anatomy, realistic
---
# The Smirk:
close-up portrait, three-quarter angle.
one corner of the mouth lifted in a half-smile.
eye on the near side narrowed slightly, knowing.
chin tucked, head tilted toward the camera.
eyebrow raised on the same side as the lifted corner.
Looking directly into camera. Knowing, teasing.
Perfect anatomy, realistic
---
# The Gasp:
close-up portrait, head thrown back slightly.
mouth open in a soft gasp, lips parted.
eyes wide, looking upward through the lashes.
throat exposed, Adam's apple or neck tendons visible.
cheeks slightly hollowed from the inhale.
Looking upward, not at camera. Surprised, caught.
Perfect anatomy, realistic
---
# The Pout:
close-up portrait, lower lip pushed forward slightly.
eyes looking up through the lashes, head tilted down.
cheeks slightly sucked in, creating hollows.
chin lifted, neck stretched.
Looking up into camera. Demanding, petulant.
Perfect anatomy, realistic
---
# The Flutter:
close-up portrait, eyes closed, lashes resting on the cheeks.
head tilted to one side, lips slightly parted.
breath slow, chest barely rising.
eyelids trembling slightly as if about to open.
Looking down, then opening eyes into camera. Anticipating, trembling.
Perfect anatomy, realistic
---
# The Stare:
close-up portrait, face square to camera.
eyes wide open, unblinking, intense gaze fixed directly into the lens.
brows slightly furrowed, mouth closed, neutral.
head perfectly centered, no tilt.
Looking directly into camera. Unflinching, commanding.
Perfect anatomy, realistic
---
# The Lick:
close-up portrait, tongue extended, tip touching the center of the upper lip.
eyes looking directly into camera, half-lidded.
head tilted slightly back, chin lifted.
cheeks slightly hollowed.
Looking directly into camera. Tasting, deliberate.
Perfect anatomy, realistic
---
# The Bound Wrists:
kneeling upright, knees apart, sitting back on the heels.
wrists bound together in front of the body with a silk ribbon or rope.
arms extended forward, bound wrists resting on the thighs.
head bowed, chin near the chest.
torso upright, spine long, shoulders relaxed.
Looking down, not at camera. Submissive, restrained.
Perfect anatomy, realistic
---
# The Collar Leash:
kneeling upright, knees together, sitting back on the heels.
neck encircled by a thin collar or choker.
arms behind the back, wrists bound or clasped.
head tilted back, chin lifted, throat exposed.
leash extending upward from the collar, implied tension.
Looking upward, not at camera. Leashed, controlled.
Perfect anatomy, realistic
---
# The Shibari Chest:
standing, arms at the sides.
rope wrapped in a diamond pattern across the chest and torso, binding the arms to the body.
shoulders pulled back, chest presented by the tension of the rope.
head tilted to one side, eyes half-closed.
legs slightly apart, weight on both feet.
Looking directly into camera. Bound, displayed.
Perfect anatomy, realistic
---
# The Ankle Cuff:
lying on back, legs extended straight up toward the ceiling.
ankles bound together with a leather cuff or silk band.
arms extended overhead along the ground, palms up.
hips flat on the ground, lower back pressed down.
head turned to the side, watching the bound legs.
Looking at the legs, then into camera. Elevated, secured.
Perfect anatomy, realistic
---
# The Wrists Overhead:
standing, arms extended straight overhead.
wrists bound together, arms pulled upward by an implied anchor.
torso stretched long, ribs visible, abdomen taut.
legs together, feet flat, weight on the balls of the feet.
head tilted back, looking up at the bound wrists.
Looking upward, not at camera. Stretched, suspended.
Perfect anatomy, realistic
---
# The Thigh Bind:
lying on side, bottom leg extended straight.
top leg bent at the knee, thigh bound to the calf with a silk ribbon.
arms bound behind the back at the wrists.
head resting on the ground, turned toward the camera.
body forming a compressed, bound S-curve.
Looking directly into camera. Compressed, bound.
Perfect anatomy, realistic
---
# The Blindfold:
kneeling upright, knees apart, sitting back on the heels.
eyes covered by a silk blindfold, fabric tied at the back of the head.
arms behind the back, wrists bound.
head tilted slightly upward, lips parted.
shoulders relaxed, chest open.
Looking upward blindly, not at camera. Sensory, deprived.
Perfect anatomy, realistic
---
# The Rope Harness:
standing, legs apart.
rope wrapped in a harness pattern around the hips and between the legs, creating a web across the pelvis.
arms free at the sides or clasped behind the back.
head thrown back, neck stretched.
weight on one leg, opposite hip popped.
Looking upward, not at camera. Webbed, caught.
Perfect anatomy, realistic
---
# Implied Restraint
You are lying on your back on a bed.
Arms stretched out to the sides, wrists resting softly, fingers slightly curled. No visible restraints but body language suggesting stillness. Legs straight, slightly parted. Looking into the camera with calm, trusting eyes. Minimalist boudoir lighting. The suggestion of restraint through pose alone. Tasteful, artistic.
realistic
---
# Wrists Together, Loose
You are lying on your back.
Arms raised above her head, wrists held together loosely as if by her own will.
Fingers relaxed, palms facing each other.
Legs drawn up slightly, knees together. Looking directly into the camera. Soft natural light. The implication of restraint just beginning. Elegant boudoir photography.
realistic
# Silk Suggestion
You are lying on your back. Arms stretched to the sides, a silk ribbon loosely draped across each wrist, trailing off-frame, not taut.
Legs bent, ankles crossed. One ribbon visible near an ankle.
Looking into the camera with a knowing, slightly vulnerable expression. Soft, warm lighting. Subtle introduction of prop. Artistic boudoir restraint.
realistic
# Wrists Bound Above Head
You are lying on your back on a bed.
Both arms pulled above her head, wrists visibly bound together with soft silk or fabric. Ribbon tied to a headboard or held off-frame. Tension visible in her extended arms but face remains calm. Legs straight, one knee slightly bent. Looking upward toward the camera. Moody, intimate lighting. Tasteful restrained boudoir.
realistic
# Spread-Eagle Begins
You are lying on your back, arms stretched wide to both sides, each wrist bound with silk to the bed frame.
Ribbons visibly taut.
Legs spread slightly, one ankle loosely bound, the other free. Chest lifted slightly with breath. Looking into the camera with a mix of vulnerability and invitation. Darker, more dramatic lighting. Artistic bondage-lite photography.
realistic
# Full Spread Restraint
You are lying on your back, fully spread-eagle.
Both wrists bound to the sides of the bed, ribbons taut against the pull of her arms. Both ankles bound wide to the corners of the bed. Body stretched, back slightly arched. Head tilted back, eyes looking into the camera. Musculature visible from the tension of being held open. Dramatic shadow and light. Elegant, intense boudoir bondage.
realistic
# Knees Pulled Back
You are lying on your back.
Wrists bound above her head to a central point. Legs drawn up, knees pulled toward chest and held apart by silk ties running from ankles to the sides of the bed. Hips lifted slightly. Abdomen tensed. Looking at the camera with an expression of sweet submission. Soft but directional lighting highlighting the body's curves. Artistic shibari-influenced pose.
realistic
# Crossed-Ankle Hogtie Suggestion
You are lying on your stomach on a bed.
Arms stretched behind her back, wrists crossed and bound with silk at the small of her back. Ankles also crossed and bound, a silk cord running from ankles to wrists, pulling her body into a gentle arch. Head turned to the side, cheek resting on the bed, eyes looking into the camera. Hair tousled. Moody, intimate lighting. Tasteful artistic hogtie reference.
realistic
# Wrists Behind Back
You are seated on a simple wooden chair.
Arms pulled behind her back, wrists cuffed together with polished metal shackles at the small of her back. Shoulders rolled back, posture forced upright by the restraint. Legs together, ankles bound to the chair legs with matching metal cuffs. Looking directly into the camera with a composed, defiant expression. Single harsh overhead light. Cold, industrial restraint aesthetic. Artistic interrogation-themed boudoir photography.
realistic
# Arms Overhead to Chair Back
You are seated on a chair, torso leaning forward slightly.
Arms stretched up and behind her, wrists bound high on the backrest of the chair, pulling her shoulder blades together. Ankles cuffed wide to each front chair leg. Back arched from the tension. Head tilted down, then eyes lifted to the camera. Metallic gleam of cuffs catching the light. Dark, cinematic lighting. Vulnerable yet beautiful restraint composition.
realistic
# Straddling, Bound to Chair Back
You are straddling a chair backwards, facing the camera.
Arms wrapped around the chair back, wrists cuffed together on the far side. Chest pressed against the wood. Ankles cuffed to the back chair legs, knees spread by the seat width. Chin resting on the chair back, eyes looking into the lens. Metal restraints visible at wrists and ankles. Cool blue-toned lighting. Intimate, intense artistic restraint portrait.
realistic
# Wrists to Ankles, Kneeling
A female kneeling on a cold concrete floor. Arms threaded between her legs, wrists cuffed to her ankles behind her, forcing a tight, folded position. Body curled forward, forehead nearly touching the ground. Hair falling over her face, one eye visible looking toward the camera. Heavy metal cuffs and short chain connecting all four limbs. Bare industrial setting. Harsh spotlight. The most physically restrictive body fold. Artistic captivity photography.
realistic
# Spreader Bar Between Ankles
A female standing against a bare wall. Arms pulled above her head, wrists shackled to a metal ring bolted high on the wall. Ankles cuffed wide apart to a steel spreader bar, legs forced open. Body stretched long, standing on tiptoes slightly from the upward pull. Looking down toward the camera with an expression of endurance. Cold metallic tones. Industrial, stark lighting. Restrained architectural body lines.
realistic
# Standing Wall Restraint
A female standing with her back pressed against a cold metal wall. Wrists shackled to rings at shoulder height on either side. Ankles cuffed to rings at floor level, legs spread. A heavy metal collar around her neck, chained to a ring behind her head, limiting forward movement. Body flat against the surface, barely able to shift. Eyes wide, looking straight into the camera. Institutional, severe restraint. Clinical lighting. Most extreme wall-based pose.
realistic
# Arms and Legs Spread
A female suspended in a standing spread position within a metal bondage frame. Wrists shackled to the upper corners of the frame, arms fully extended upward and outward. Ankles shackled to the lower corners, legs spread wide. Waist cinched to a vertical bar with a metal belt, preventing any torso movement. Head upright, eyes meeting the camera. The body held in a perfect X-shape, utterly immobilized. Sterile, dungeon aesthetic. Architectural restraint photography.
realistic
# Bent Over Bar
A female bent forward over a horizontal metal bar at waist height. Arms pulled forward and downward, wrists cuffed to rings on the bar near the floor. Ankles cuffed wide to floor rings behind her. Torso draped over the cold metal, back curved downward, completely exposed and helpless. Head turned sideways, cheek nearly touching the bar, eyes looking toward the camera. Steam or cold atmosphere. Dungeon lighting. One of the most vulnerable restraint configurations.
realistic
# Strappado Prelude
A female standing, arms pulled behind her back and lifted upward by a chain running from her shackled wrists to a ceiling point. The pull forces her to bend forward at the waist, body forming a right angle. Ankles cuffed to floor rings, preventing any adjustment. Hair hanging down, face partially visible as she looks toward the camera. Muscles tensed, shoulders straining. Harsh overhead bulb. The most physically demanding restraint pose — strappado position. Artistic endurance photography.
realistic
# Full Chair Immobilization
A female fully immobilized on a heavy metal restraint chair. Wrists shackled to armrests, forearms strapped down with thick leather. Ankles locked to the front legs with metal cuffs. A steel waist band pinning her torso to the chair back. A metal collar around her neck, chained to a ring at the top of the chair, preventing any head movement. Only her eyes can move — looking directly into the camera. Legs separated by a central bar. Complete, absolute restraint. Dark, final-level dungeon aesthetic. Cold metallic surfaces. The most restrained state possible while remaining seated and composed.
realistic
# Steel Slab — Four-Point Supine Lockdown
A female lying on her back on a cold steel slab. Wrists locked into recessed metal cuffs bolted flush to the surface, arms stretched wide. Ankles similarly locked into cuffs at the far corners, legs spread and straight. A heavy steel band across her waist, bolted down on both sides, pinning her hips flat. A thick metal collar around her neck, bolted to the slab behind her head. Zero range of motion. Eyes staring upward toward the camera positioned directly overhead. Harsh clinical lighting with cold blue-white tone. Sterile, merciless, completely inescapable. Industrial medical-restraint fusion aesthetic.
realistic
# Vertical Steel Frame — Full Suspension Immobilization
A female suspended upright inside a heavy steel rectangular frame. Wrists shackled high to the upper corners, arms pulled fully extended above her head. Ankles shackled wide to the lower corners. A thick steel belt cinched around her waist, bolted to both sides of the frame, holding her torso fixed in space. A metal collar chained to the top bar. Thigh bands pulling her legs slightly apart, bolted to the side bars. Every major joint controlled. Body floating immobile within the steel rectangle. Looking into the camera with an expression of total surrender. Cold dungeon lighting, steel reflections. The most absolute standing restraint.
realistic
# Inverted Steel Restraint — Ankles Above
A female suspended from a steel beam by her ankles. Heavy metal cuffs locked around both ankles, chain running upward to a motorized hoist. Arms pulled downward and behind her back, wrists cuffed to a steel ring bolted to the floor, creating a long, taut diagonal line from ankles to wrists. Body hanging fully extended, hair sweeping the floor. A steel waist belt chained to a floor ring, preventing any sway. Fully inverted, utterly helpless. Camera positioned low, looking up toward her face. Dark industrial setting with a single harsh light cone. Extreme artistic restraint.
realistic
# Steel Coffin Position - Six-Point
A female lying supine inside a shallow steel tray or open metal coffin. Wrists cuffed to the sides at hip level. Elbows also strapped down with steel bands. Ankles cuffed to the foot end. Knees held down by a heavy steel bar bolted across her thighs. Waist cinched by a wide metal band bolted to the tray floor. A metal collar locked to the head end. Six discrete points of total immobilization. Only her face and fingers can move. Eyes looking up into the camera hovering directly above. Cold metallic sheen, dark void surrounding the tray. Clinical, terrifying stillness. Maximum mechanical restraint.
realistic
# Steel Stockade - Neck Wrists Ankles
A female bent forward at the waist, secured in a heavy steel stockade. Thick metal board with three holes: neck locked in the center, both wrists locked to either side. Ankles locked into a separate lower stockade bar, legs spread wide. Waist pushed against a steel support, hips immobilized. Body folded at ninety degrees, completely exposed from behind, face visible from the front. Eyes looking up toward the camera positioned low in front of her. Rusted or oiled steel texture. Harsh spotlight. Medieval-severe restraint aesthetic, utterly dehumanizing in its mechanical simplicity.
realistic
# Steel Cage Restraint Spread
A female inside a small steel cage, barely larger than her body. Wrists shackled to the top bars of the cage, arms pulled upward. Ankles shackled to the bottom corners, legs spread to the cage width. A steel collar chained to the back wall, pulling her head against the bars. Waist belt bolted to the rear wall. She cannot stand fully, cannot sit, cannot turn. Fingers gripping the bars. Face pressed between two vertical bars, eyes looking out at the camera. The cage itself becomes the restraint device. Dungeon lighting, bars casting shadows across her body. Maximum confinement.
realistic
# Steel Gantry — Full Suspension Face Down
A female suspended face-down from a steel gantry. Wrists shackled above her head, pulled upward toward the gantry beam. Ankles shackled and pulled wide apart by chains running to separate points on the gantry. A wide steel belt around her waist, chained upward to the beam, holding the center of her body. A metal collar with a chain running forward, pulling her head up slightly. Body suspended horizontally in mid-air, fully extended, utterly immobilized, floating above the floor. Camera below looking up at her face. Industrial warehouse lighting. The most extreme suspension restraint.
realistic
# Steel Chair — Ten-Point Lockdown
A female seated on a heavy steel chair bolted to the floor. Wrists locked to the armrests with double cuffs — one at the wrist, one at the forearm. Ankles cuffed to the front legs. Knees held apart by a steel spreader bar locked to the chair seat. A metal waist band bolted to the chair back. A steel chest strap bolted across her upper torso just below the collarbone. A metal collar locked to the chair back, holding her head immobile. A steel band across her forehead, bolted to the headrest. Ten discrete points of absolute fixation. Only her eyes can move. Camera directly in front, at eye level. The most comprehensively restrained seated position possible.
realistic
# Vertical Body Wrap
A female wrapped around a thick vertical steel pipe, floor to ceiling. Wrists cuffed behind the pipe, pulled together at the small of her back. Ankles cuffed behind the pipe at the base. A steel waist belt bolted through the pipe, cinching her torso against the cold metal. A metal collar chained tightly around the pipe, cheek pressed against the steel. Knees cuffed around the pipe. Body molded to the cylinder, arms and legs wrapped backward, unable to slide up or down. Helpless embrace of cold metal. Camera circling to catch her one visible eye. Brutalist industrial setting, single harsh light. Total body-to-object fusion restraint.
realistic
# The Steel Cruciform, Fully Enclosed
A female locked into a massive steel cruciform structure. Wrists shackled into recessed steel blocks at the ends of the horizontal beam, fingers trapped. Ankles similarly locked into blocks at the base. A steel corset bolted to the vertical beam, encasing her from hips to ribs, bolted in eight places. A steel chest plate bolted across her sternum. A metal collar locked to the beam behind her neck. A steel band across her forehead. A steel bar running vertically between her legs, bolted to the waist corset and the base plate, preventing any leg movement. Metal plates bolted over her upper arms and thighs. Nearly every inch of her body in contact with unyielding steel. Eyes visible through the gaps, looking at the camera. Extreme industrial lighting, sparks or steam. The absolute maximum restraint — the body as a component of the machine.
realistic
# The Iron Maiden — Opened Shell Restraint
A female standing inside an opened iron maiden device. The heavy steel door swung wide, revealing the interior lined with blunt metal nubs and contour-fitted restraints. Wrists locked into recessed cuffs on the inner walls, arms spread. Ankles locked into cuffs at the base. A steel collar at the back holding her neck. A waist band bolted to the rear shell. The door hangs open beside her, rows of dull interior spikes visible, threatening closure. She stands perfectly still, eyes looking toward the camera with the knowledge of what the closed device means. Dark Gothic chamber, torchlight flickering. Medieval infernal restraint, the threat of impalement held in suspension.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Brazen Bull — Interior Restraint
A female secured inside the hollow brass interior of a brazen bull device. The massive bronze bull shaped chamber opened along its side hatch, revealing her curled inside. Wrists shackled to rings on the heated-looking bronze walls. Ankles shackled to the floor of the chamber. A bronze collar chained to the ceiling of the interior, forcing her head back. Curled fetal within the beast's belly. The hatch door open, camera looking in at her from outside. Faint orange glow suggesting fire beneath. Hellenistic infernal restraint, the body made offering inside the sacrificial machine. Sweat on skin catching bronze reflections.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Catherine Wheel — Bound to the Spokes
A female bound to a massive wooden-and-steel breaking wheel mounted vertically on an axle. Wrists lashed with iron cuffs to the outer rim at the ten and two positions. Ankles cuffed to the rim at the four and eight positions. Iron bands across her waist and chest bolting her to the central hub. Body spread-eagled across the wheel's face. The wheel positioned so she hangs slightly forward, weight pulling against the restraints. Camera looking up at her from below. Dark torture chamber, implements on walls. Medieval infernal restraint, the body readied for the wheel's turning and the iron bar's work.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Judas Cradle — Suspended Above
A female suspended in a harness above a pyramidal wooden Judas cradle device. Wrists bound behind her back with iron shackles chained to a ceiling pulley. Ankles bound and pulled wide by chains to floor rings on either side. The pointed apex of the pyramid positioned directly beneath her, barely an inch below. Her weight held entirely by the pulley system, trembling slightly. Face looking down at the device beneath her, then up at the camera with dread. Dark stone chamber, single beam of light. The infernal device as imminent threat, restraint as the pause before descent.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Iron Spider — Multi-Arm Mechanical Restraint
A female trapped within an articulated iron spider device. A central steel harness locked around her torso, bolted to a vertical stand. Six jointed mechanical arms extending from the harness, each ending in a steel cuff — wrists locked into two upper arms pulled high and wide, ankles locked into two lower arms spread apart, thighs gripped by two middle arms. The mechanical arms fully extended, holding her suspended in a rigid star pattern, feet off the ground. Gears and rivets visible on the device. Steam or oiled iron aesthetic. Head free but body claimed by the machine. Camera circling the device. Steampunk-infernal fusion. The body as prey in a mechanical predator's grip.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Heretics Fork — Neck-to-Waist Immobilization
A female restrained with a steel heretic's fork device. A rigid iron bar with a two-pronged fork at each end, one fork pressed beneath her chin, the other pressed against her sternum just above the breasts. A thick leather and iron collar at the back of her neck locking the upper fork in place, a steel chest strap locking the lower fork. Her head forced upright, unable to lower her chin or tilt forward without the prongs digging in. Wrists cuffed behind her back. Ankles shackled together. Kneeling on a stone floor. Eyes wide, head held perfectly erect by the prongs. Camera at her level. Inquisitorial infernal restraint, torment through enforced stillness.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Scavengers Daughter — Compressive Iron Hoop
A female compressed into a scavenger's daughter device. A heavy iron hoop forcing her body into a tight crouching ball. The iron band circling behind her knees, over her shoulders, and under her feet, a single continuous ring cinched tight with a threaded bolt mechanism. Wrists shackled to the iron band at her sides. Ankles locked to the band beneath her. Body folded into a tight sphere of flesh and iron, knees pressed to chest, head forced down. Lying on her side on a stone floor. Camera looking down at the compressed form. One eye visible between her knees and the iron. Tudor infernal restraint, the body crushed into itself by the device's geometry.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Pear of Anguish — Internally Threatened
A female restrained on her back on a slanted wooden board. Wrists shackled above her head to the top of the board. Ankles shackled wide to the bottom corners. Knees bent and held apart by an iron spreader bar. An iron pear device — a segmented metal bulb with a screw mechanism — rests on a small table beside her, its key protruding, glinting in the light. The device is not inserted but its presence is the focal threat. She looks at it, then at the camera. The restraint is the board; the infernal element is the pear waiting beside her. Cold chamber lighting. The body offered to the device, the pause before activation.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Breaking Rack — Stretched Horizontal
A female stretched fully on a wooden breaking rack. Wrists locked into leather-and-iron cuffs attached to the roller at the head of the rack, arms pulled taut overhead. Ankles locked into similar cuffs attached to the foot roller, legs pulled straight and tense. A wide leather belt across her waist, bolted to the rack bed. A chest strap pinning her torso. The ratchet mechanisms visible at both ends, handles inserted, ready for another turn. Her body already taut, muscles defined by the tension, a sheen of strain. Head tilted back, throat exposed, eyes looking toward the camera with exhausted endurance. Stone walls, torches. The ultimate medieval infernal restraint — the rack as both device and architecture of the body's limits.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Iron Chair of Complicity — Infernally Throned
A female seated upon a heavy iron throne covered in blunt pyramidal studs across the seat, backrest, and armrests. Wrists locked to the studded armrests with iron cuffs, palms pressing into the metal points. Ankles locked to the studded front legs. An iron belt bolting her waist to the studded seat. An iron collar chained to the studded backrest, forcing her shoulder blades against the points. Every surface she touches is covered in dull metal protrusions — not piercing, but relentlessly present, pressing into her flesh. She cannot shift weight, cannot adjust, cannot lean away. The discomfort is constant, the throne itself an instrument. She sits as queen of the infernal chamber, eyes looking down at the camera with a complex expression — power, torment, surrender, defiance.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Steel Slab — Wrist and Ankle Lockdown
A female lying on her back on a featureless steel slab, no background, infinite black void. Wrists locked into minimalist steel cuffs bolted flush to the slab, arms stretched straight to the sides. Ankles locked into identical flush cuffs, legs spread straight. A single thin steel band across the waist, bolted through the slab. No other details. Body stark against the black. Studio lighting, cold white. Steel and skin only.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Standing Steel Frame — Minimalist Four-Point
A female standing within a simple rectangular steel frame, suspended in black void. The frame is clean, unadorned, no visible bolts or joints. Wrists shackled to the upper corners with thin steel cuffs. Ankles shackled to the lower corners. A thin steel band at the waist connected to both sides of the frame. No floor visible. Body floating centered in the steel rectangle. Clean industrial lines. High-contrast lighting. Absolute minimalism.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Steel Post — Arms Overhead
A female standing against a single vertical steel post rising from the void. Arms pulled overhead, wrists cuffed together around the post above her head. Ankles cuffed together around the base of the post. A thin steel band circling her waist and the post. Body pressed against cold metal, stretched long. Black void all around. Single key light from one side. Elemental composition — one post, one body, three restraints.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Kneeling — Wrists to Ankles
A female kneeling on an invisible surface in black void. Arms threaded behind her back, wrists cuffed directly to her ankles with short steel shackles. Body folded forward, forehead nearly touching her knees. A single steel band around her thighs. No floor, no walls, no context. Hair hanging down. One eye visible. Stark lighting from above. The body as sculpture, restraint as geometry.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Steel Hoop — Compressed Sphere
A female compressed into a perfect steel hoop, floating in black void. A single continuous polished steel ring circling her body, holding her in a tight ball — knees to chest, arms wrapped around legs, head tucked down. The hoop is seamless, minimalist, industrial. Body folded within the circle. Soft lighting on skin, hard reflections on steel. No other elements. Restraint as pure geometric form.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Spreader Bar — Standing Spread
A female standing in black void, arms pulled overhead by a single horizontal steel bar, wrists cuffed to each end. Ankles cuffed to a matching spreader bar on the floor. Body forming a clean vertical line between the two bars. Waist cinched with a thin steel band, no connection to anything. Minimalist industrial hardware. Body taut, stretched between two steel lines. Studio lighting. Graphic, architectural.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Steel Collar and Chain — Vertical Suspension
A female suspended by her wrists in black void. Arms pulled straight overhead, wrists cuffed together with a single steel shackle, chain rising into the darkness above. A steel collar around her neck, a taut chain descending to a cuff around both ankles, pulling her body into a slight arch. Toes barely touching nothing. Three points of tension — wrists up, neck down, ankles up. Body as tensioned cable. Perfect black background. Cold light from above.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Single Steel Band — Total Body Wrap
A female standing in black void, arms pinned to her sides by a series of five thin, evenly spaced steel bands — one at the ankles, one below the knees, one at the thighs, one at the waist and elbows, one at the chest and upper arms. No other restraints. Body held perfectly straight, mummified in minimalist rings. Head free, looking directly at camera. Steel and skin, repetition, rhythm. Museum lighting. The body as minimalist art object.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Hanging X — Cruciform Suspension
A female suspended in an X-shape in black void. Wrists cuffed to two separate steel chains rising diagonally into the darkness above. Ankles cuffed to two chains descending diagonally into the void below. Body floating center-frame, fully extended, arms and legs forming the perfect X. A thin steel band at the waist, connected to nothing. Five points of tension from nowhere. Pure graphic silhouette. High-contrast black and white lighting. Absolute minimalist restraint.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Cube — Six-Sided Steel Cage Minimalism
A female enclosed within a perfectly minimalist steel cube floating in black void. The cube is constructed of thin square-section steel tubing, edges only, no panels — an open wireframe. Her wrists cuffed to the top front edge. Ankles cuffed to the bottom front corners. Waist cinched to the rear vertical edge with a thin steel band. Body suspended centered within the transparent cage, visible from all angles. The cube is her only context. Camera outside looking in through the open faces. Clean geometric lines, body within the Platonic solid. Lighting soft on her, hard on the steel edges. The most restrained — geometry itself as prison.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Single Steel Line — Full Body Chain
A female standing in black void.
A single continuous polished steel chain wrapping her body from ankles to shoulders — circling ankles, knees, thighs, waist, ribs, upper arms, and wrists behind her back.
One seamless line of restraint holding her perfectly vertical.
No floor, no anchor points.
Body and chain suspended in darkness.
Cold studio light. Steel and skin.
Absolute purity of form.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Welded Cage — Sealed Within
A female sealed inside a minimalist steel box frame floating in black void. Thin square-section steel tubing forming a perfect rectangular cage around her body, sized exactly to her dimensions. Wrists welded to the interior side rails. Ankles welded to the base rails. Waist welded to the rear vertical rail. No door, no hinges, no escape — she is part of the object now. Camera circling outside. Museum lighting. Body as permanent installation.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Steel Monolith — Recessed Immobilization
A female embedded into the face of a massive floating steel monolith in black void. The monolith is perfectly smooth except for recessed channels holding her body — wrists locked into carved grooves, ankles locked into lower grooves, a polished steel band across her waist bolted flush to the surface. Body pressed flat against the cold metal, unable to flex or shift. Face turned to the side, one cheek against steel. The monolith extends infinitely upward and downward into darkness. Cosmic minimalist restraint — the body on the face of the absolute.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Suspended Grid — Nine Points
A female suspended at the center of a minimalist steel grid floating in black void. The grid is a perfect square of thin steel bars. Wrists locked to two upper intersection points. Elbows locked to two mid-level points. Ankles locked to two lower points. Knees locked to two points between. Waist cinched to the central vertical bar. Nine discrete connections holding her in a perfectly symmetrical spread. Head free, center frame. Camera directly in front. Technical precision restraint — the body plotted on coordinates.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Steel Column — Total Vertical Entrapment
A female standing inside a seamless polished steel cylinder floating in black void. The column is just wider than her body, open at the top and bottom. Her arms pinned straight against her sides by the cylinder walls. Her ankles cuffed to a steel ring at the base. Her neck enclosed in a steel collar bolted to the rim at the top. Body entirely encased from ankles to chin in smooth steel. Only her head visible above the rim, looking directly at camera. The cylinder reflects nothing but void. Absolute vertical confinement — the body as core within the column.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Mirror Steel — Infinite Restraint Reflection
A female restrained between two perfectly polished steel planes floating parallel in black void — one in front, one behind. Wrists locked to the front plane, ankles locked to the rear plane, body suspended horizontally between them. A steel band around her waist connected to both planes. Her reflection repeating infinitely into both surfaces. The planes are close enough that she can barely shift. Camera positioned to capture her face and the infinite reflections. Cold, infinite restraint — the body multiplied into eternity between mirrors.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Single Point Suspension — Total Tension
You are suspended from a single steel point high in black void.
A minimalist steel harness — thin bands at wrists, elbows, waist, knees, and ankles — all converging to a single master ring above your head via clean steel cables.
Body pulled upward into a taut, straight vertical line, toes pointed down.
Every limb drawn to the single point, body unified in tension.
Head slightly back. Soft light on skin, hard glint on the convergence point above.
Restraint as singular geometry — all force to one origin.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Steel Ribcage — External Skeleton
You are encased in a minimalist steel exoskeleton floating in black void.
Thin steel ribs curving from a central spine bar behind you, wrapping around your torso, waist, thighs, and upper arms.
Not a cage — an external skeleton bolted shut along your front.
Wrists locked to the hip-level ribs.
Ankles locked to the lowest ribs.
Neck enclosed in a thin steel ring at the top of the spine bar.
Body held within a second skeleton of polished steel.
You breathe against it.
Restraint as exoskeletal fusion.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# The Flat Plane — Compression Restraint
You are compressed between two seamless steel planes floating horizontally in black void — one above, one below. The gap between them is exactly the depth of her body. Wrists locked to the upper plane, ankles locked to the lower plane, body pressed flat. She cannot arch, cannot lift, cannot turn. Face visible through a rectangular opening in the upper plane, eyes looking up at the camera positioned directly overhead. The planes extend past the frame edges into darkness. Infinite compression. The body as a thin layer of warmth between two cold absolutes.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise
# Total Enclosure — Steel Sarcophagus
You are sealed within a minimalist steel sarcophagus floating upright in black void. The sarcophagus is perfectly smooth, seamless, rectangular — no ornament, no hinges visible. A single thin vertical slit at face level reveals her eyes looking out. Her body entirely encased, immobilized, unseen. The exterior is polished to a mirror finish, reflecting only the black void and the camera's lens. No cuffs visible, no restraints visible — the sarcophagus itself is the total restraint. The body has become interior. The steel is final. Absolute minimalist full restraint — the body as secret held within the object.
you are looking into the camara and keeping facial characteristics as reference photo, Realistic, anatomically precise