diff --git a/backlog.md b/backlog.md
index 44a4168..45034a7 100644
--- a/backlog.md
+++ b/backlog.md
@@ -1 +1,4 @@
-privacy feature not work when overlay
\ No newline at end of file
+privacy feature not work when overlay
+
+archive (anders dan delete)
+delete action (closes screen?)
\ No newline at end of file
diff --git a/tour-comfy/edit_api.py b/tour-comfy/edit_api.py
index bcc8cc4..59da42d 100644
--- a/tour-comfy/edit_api.py
+++ b/tour-comfy/edit_api.py
@@ -146,6 +146,14 @@ def on_startup():
print(f"[wireframe] mounted {wf_dir} → /wireframe")
except Exception as e:
print(f"[wireframe] mount warning: {e}")
+ # Mount output dir so images can be served via HTTP (/output/filename.png)
+ try:
+ out_dir = _load_output_dir()
+ if os.path.isdir(out_dir):
+ app.mount("/output", StaticFiles(directory=out_dir), name="output")
+ print(f"[output] mounted {out_dir} → /output")
+ except Exception as e:
+ print(f"[output] mount warning: {e}")
# --- helpers ----------------------------------------------------------------
@@ -1757,16 +1765,40 @@ class SceneryRequest(BaseModel):
seed: int = -1
+def _make_side_by_side(img1: Image.Image, img2: Image.Image,
+ max_h: int = 1024) -> Image.Image:
+ """Combine two images side by side at the same height (capped at max_h)."""
+ target_h = min(max(img1.height, img2.height), max_h)
+ r1 = target_h / img1.height
+ r2 = target_h / img2.height
+ w1, w2 = int(img1.width * r1), int(img2.width * r2)
+ img1_r = img1.resize((w1, target_h), Image.LANCZOS)
+ img2_r = img2.resize((w2, target_h), Image.LANCZOS)
+ out = Image.new("RGB", (w1 + w2, target_h))
+ out.paste(img1_r, (0, 0))
+ out.paste(img2_r, (w1, 0))
+ return out
+
+
def _scenery_worker(job_id: str, model_filename: str, scene_pil: Image.Image,
prompt: str, seed: int):
output_dir = _load_output_dir()
try:
model_path = os.path.join(output_dir, model_filename)
model_pil = Image.open(model_path).convert("RGB")
- png_bytes = _run_pipeline(model_pil, prompt, seed, MAX_AREA,
- extra_images=[scene_pil])
+
+ # image1=scene (→ Picture 1, output sized to scene), image2=person (→ Picture 2)
+ # The node prepends "Picture 1:
Picture 2:
" to the prompt so the
+ # model can reason about both images by name.
+ png_bytes = _run_pipeline(
+ scene_pil.convert("RGB"), prompt, seed, MAX_AREA,
+ extra_images=[model_pil],
+ )
ts = time.strftime("%Y%m%d_%H%M%S")
base_name = naming.get_base_name(model_filename)
+ # Ensure .png extension
+ if not base_name.lower().endswith('.png'):
+ base_name = os.path.splitext(base_name)[0] + '.png'
out_name = f"{ts}_sc_{base_name}"
out_path = os.path.join(output_dir, out_name)
with open(out_path, "wb") as f:
@@ -1816,9 +1848,11 @@ def generate_scenery(req: SceneryRequest):
raise HTTPException(400, "Provide scene_bytes or scene_video")
prompt = req.prompt or (
- "Place this person into the provided scene. Keep the person's appearance, "
- "lighting, and pose natural and consistent with the environment. "
- "Photorealistic, high quality."
+ "Place the person from Picture 2 naturally inside the environment shown in Picture 1. "
+ "Keep the person's face, body proportions, clothing and pose exactly as in Picture 2. "
+ "Use the location, lighting and atmosphere from Picture 1 as the background. "
+ "Match the color temperature and shadows so it looks like one photograph taken on location. "
+ "Output a single photorealistic image. High quality, detailed."
)
job_id = uuid.uuid4().hex[:8]
@@ -1850,7 +1884,7 @@ def _load_sam2():
from sam2.automatic_mask_generator import SAM2AutomaticMaskGenerator
with open(CONFIG_PATH) as f:
conf = json.load(f)
- ckpt = os.path.expanduser(conf.get("sam2_checkpoint", "~/.sam2/sam2.1_hiera_tiny.pt"))
+ ckpt = os.path.expanduser(conf.get("sam2_checkpoint", "~/.sam/sam2.1_hiera_base_plus.pt"))
cfg = conf.get("sam2_config", "configs/sam2.1/sam2.1_hiera_t.yaml")
if not os.path.exists(ckpt):
raise FileNotFoundError(f"SAM2 checkpoint not found: {ckpt}")
diff --git a/tour-comfy/poses.md b/tour-comfy/poses.md
index 644fada..d086a59 100644
--- a/tour-comfy/poses.md
+++ b/tour-comfy/poses.md
@@ -102,7 +102,7 @@ One side grounded and stable — hand and knee firmly planted, muscles taut.
Back arched upward, hips lowered, head lifted looking into camera.
Perfect anatomy, realistic.
-# The kneeler:
+# The kneeler (beta):
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.
@@ -121,7 +121,7 @@ Lean slightly into the pose, showcasing the cross-legged position and the symmet
Highlight the smooth curves of the body and the intricate pose.
Realistic, perfect anatomy
-# The Celestial:
+# The Celestial (beta):
Looking into the camera with strong eye contact and a serene, confident expression.
Lie on your back with your arms stretched out to the sides.
Bring your legs up to your chest and cross them.
diff --git a/tour-comfy/watcher.log b/tour-comfy/watcher.log
index bac5c75..a4a2a65 100644
--- a/tour-comfy/watcher.log
+++ b/tour-comfy/watcher.log
@@ -2070,3 +2070,27 @@ SyntaxError: broken PNG file (chunk b'END\xae')
2026-06-21 04:05:41,577 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
2026-06-21 04:05:41,578 - INFO - Output directory: /mnt/zim/tour-comfy/output
2026-06-21 04:05:41,578 - INFO - API URL: http://127.0.0.1:8500/edit
+2026-06-21 04:29:45,612 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
+2026-06-21 04:29:45,612 - INFO - Output directory: /mnt/zim/tour-comfy/output
+2026-06-21 04:29:45,612 - INFO - API URL: http://127.0.0.1:8500/edit
+2026-06-21 04:50:28,202 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
+2026-06-21 04:50:28,202 - INFO - Output directory: /mnt/zim/tour-comfy/output
+2026-06-21 04:50:28,202 - INFO - API URL: http://127.0.0.1:8500/edit
+2026-06-21 05:11:05,523 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
+2026-06-21 05:11:05,523 - INFO - Output directory: /mnt/zim/tour-comfy/output
+2026-06-21 05:11:05,523 - INFO - API URL: http://127.0.0.1:8500/edit
+2026-06-21 05:13:40,995 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
+2026-06-21 05:13:40,995 - INFO - Output directory: /mnt/zim/tour-comfy/output
+2026-06-21 05:13:40,995 - INFO - API URL: http://127.0.0.1:8500/edit
+2026-06-21 05:13:53,419 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
+2026-06-21 05:13:53,419 - INFO - Output directory: /mnt/zim/tour-comfy/output
+2026-06-21 05:13:53,419 - INFO - API URL: http://127.0.0.1:8500/edit
+2026-06-21 05:30:35,120 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
+2026-06-21 05:30:35,120 - INFO - Output directory: /mnt/zim/tour-comfy/output
+2026-06-21 05:30:35,120 - INFO - API URL: http://127.0.0.1:8500/edit
+2026-06-21 05:51:41,030 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
+2026-06-21 05:51:41,030 - INFO - Output directory: /mnt/zim/tour-comfy/output
+2026-06-21 05:51:41,030 - INFO - API URL: http://127.0.0.1:8500/edit
+2026-06-21 11:04:28,350 - INFO - Watcher started. Monitoring /mnt/zim/tour-comfy/stage...
+2026-06-21 11:04:28,350 - INFO - Output directory: /mnt/zim/tour-comfy/output
+2026-06-21 11:04:28,350 - INFO - API URL: http://127.0.0.1:8500/edit