Download index.html from LiveFaceSwapAI/face-swap-reference-prep: direct link, hf CLI and curl.
- Browser
- Download file 18.2 kB
-
https://huggingface.co/spaces/LiveFaceSwapAI/face-swap-reference-prep/resolve/main/index.html
- Command line
-
hf download hf://spaces/LiveFaceSwapAI/face-swap-reference-prep/index.html
-
curl -L -o index.html https://huggingface.co/spaces/LiveFaceSwapAI/face-swap-reference-prep/resolve/main/index.html
18.2 kB
| <html lang="en"> | |
| <head> | |
| <meta charset="utf-8" /> | |
| <meta name="viewport" content="width=device-width, initial-scale=1" /> | |
| <meta name="description" content="Prepare a clear portrait reference for LiveFaceSwap AI real-time face swap. Fix orientation, position a square crop, and export a clean RGB PNG locally in your browser." /> | |
| <meta name="robots" content="index,follow" /> | |
| <link rel="canonical" href="https://huggingface.co/spaces/chris-fox/livefaceswap-reference-prep" /> | |
| <title>LiveFaceSwap AI Face Swap Reference Image Prep</title> | |
| <script type="application/ld+json"> | |
| { | |
| "@context": "https://schema.org", | |
| "@type": "SoftwareApplication", | |
| "name": "LiveFaceSwap AI Face Swap Reference Image Prep", | |
| "applicationCategory": "MultimediaApplication", | |
| "operatingSystem": "Any modern web browser", | |
| "description": "A browser-based utility that prepares authorized portrait reference images for LiveFaceSwap AI real-time face swap workflows.", | |
| "url": "https://huggingface.co/spaces/chris-fox/livefaceswap-reference-prep", | |
| "isAccessibleForFree": true, | |
| "license": "https://opensource.org/license/mit", | |
| "publisher": { "@type": "Organization", "name": "LiveFaceSwap AI", "url": "https://livefaceswap.ai/" }, | |
| "codeRepository": "https://github.com/LiveFaceSwapAI/livefaceswap-reference-prep" | |
| } | |
| </script> | |
| <style> | |
| :root { color-scheme: dark; font-family: Inter, ui-sans-serif, system-ui, -apple-system, BlinkMacSystemFont, "Segoe UI", sans-serif; background: #080d1c; color: #f4f7ff; } | |
| * { box-sizing: border-box; } | |
| html { scroll-behavior: smooth; } | |
| body { margin: 0; min-height: 100vh; background: radial-gradient(circle at 50% -10%, #273c82 0, #111936 34%, #080d1c 68%); } | |
| main { width: min(1080px, calc(100% - 32px)); margin: 0 auto; padding: 42px 0 72px; } | |
| a { color: #a9c3ff; text-underline-offset: 3px; } | |
| p, li { color: #cbd5f2; line-height: 1.68; } | |
| h1, h2, h3 { letter-spacing: -0.025em; } | |
| h1 { margin: 12px 0 16px; max-width: 880px; font-size: clamp(2.35rem, 6vw, 4.6rem); line-height: 0.98; } | |
| h2 { margin: 0 0 12px; font-size: clamp(1.55rem, 3vw, 2.15rem); } | |
| h3 { margin: 0 0 6px; font-size: 1.05rem; } | |
| .eyebrow { display: inline-flex; padding: 7px 11px; border: 1px solid #5369a4; border-radius: 999px; color: #cbd7ff; background: rgba(64, 87, 157, 0.22); font-size: 0.82rem; font-weight: 750; letter-spacing: 0.04em; text-transform: uppercase; } | |
| .lede { max-width: 790px; margin: 0; font-size: clamp(1rem, 2vw, 1.2rem); } | |
| .hero-links, .project-links { display: flex; flex-wrap: wrap; gap: 12px; margin-top: 22px; } | |
| .button-link { display: inline-flex; align-items: center; justify-content: center; min-height: 42px; padding: 10px 15px; border: 1px solid #6881c3; border-radius: 11px; color: #eef3ff; background: #16244d; font-weight: 750; text-decoration: none; } | |
| .button-link.primary { border-color: #88a8ff; background: #85a7ff; color: #07122d; } | |
| .tool { display: grid; grid-template-columns: minmax(250px, 0.8fr) minmax(300px, 1.2fr); gap: 24px; margin-top: 36px; padding: 24px; border: 1px solid #3d518b; border-radius: 22px; background: rgba(12, 20, 48, 0.91); box-shadow: 0 26px 90px rgba(0, 0, 0, 0.32); } | |
| .controls { display: grid; align-content: start; gap: 17px; } | |
| label { display: grid; gap: 8px; color: #f4f7ff; font-weight: 680; } | |
| input, select, button { width: 100%; font: inherit; } | |
| input[type="file"], select { border: 1px solid #536aa8; border-radius: 11px; padding: 11px; background: #101936; color: inherit; } | |
| input[type="range"] { accent-color: #89a9ff; } | |
| .value { color: #aebfe9; font-weight: 520; } | |
| button { min-height: 44px; border: 0; border-radius: 11px; padding: 11px 15px; background: #89a9ff; color: #07112b; font-weight: 820; cursor: pointer; } | |
| button.secondary { border: 1px solid #536aa8; background: #18264e; color: #eef3ff; } | |
| button:disabled { cursor: not-allowed; opacity: 0.45; } | |
| .preview { min-height: 430px; display: grid; place-items: center; border: 1px dashed #5268a3; border-radius: 16px; overflow: hidden; background: #060a15; } | |
| canvas { display: block; width: 100%; height: auto; max-height: 620px; object-fit: contain; } | |
| .placeholder { max-width: 34ch; padding: 32px; text-align: center; color: #93a4d0; line-height: 1.55; } | |
| .privacy { margin: 16px 2px 0; font-size: 0.91rem; } | |
| .section { margin-top: 64px; } | |
| .section-intro { max-width: 760px; margin: 0; } | |
| .workflow { display: grid; grid-template-columns: repeat(4, 1fr); gap: 14px; margin-top: 22px; } | |
| .card { padding: 19px; border: 1px solid #34477b; border-radius: 16px; background: rgba(18, 28, 61, 0.76); } | |
| .step { width: 32px; height: 32px; display: grid; place-items: center; margin-bottom: 16px; border-radius: 9px; background: #87a7ff; color: #07122c; font-weight: 850; } | |
| .card p { margin: 0; } | |
| .benefits { display: grid; grid-template-columns: repeat(3, 1fr); gap: 14px; margin-top: 22px; } | |
| .details { display: grid; grid-template-columns: 0.8fr 1.2fr; gap: 24px; align-items: start; } | |
| .details ul { margin: 12px 0 0; padding-left: 21px; } | |
| .specs { margin: 0; overflow: hidden; border: 1px solid #34477b; border-radius: 16px; background: rgba(18, 28, 61, 0.76); } | |
| .specs div { display: grid; grid-template-columns: 110px 1fr; gap: 12px; padding: 14px 16px; border-bottom: 1px solid #304272; } | |
| .specs div:last-child { border-bottom: 0; } | |
| dt { color: #f4f7ff; font-weight: 750; } | |
| dd { margin: 0; color: #cbd5f2; line-height: 1.55; } | |
| details { padding: 15px 17px; border: 1px solid #34477b; border-radius: 13px; background: rgba(18, 28, 61, 0.68); } | |
| details + details { margin-top: 10px; } | |
| summary { cursor: pointer; color: #f4f7ff; font-weight: 730; } | |
| details p { margin: 10px 0 0; } | |
| footer { margin-top: 64px; padding-top: 24px; border-top: 1px solid #2e3e6b; } | |
| footer p { max-width: 850px; font-size: 0.92rem; } | |
| @media (max-width: 820px) { .workflow, .benefits { grid-template-columns: 1fr 1fr; } .details { grid-template-columns: 1fr; } } | |
| @media (max-width: 720px) { main { padding-top: 28px; } .tool { grid-template-columns: 1fr; padding: 18px; } .preview { min-height: 310px; } .workflow, .benefits { grid-template-columns: 1fr; } .specs div { grid-template-columns: 88px 1fr; } } | |
| </style> | |
| </head> | |
| <body> | |
| <main> | |
| <header> | |
| <span class="eyebrow">LiveFaceSwap AI · Browser utility</span> | |
| <h1>Prepare a better reference image for real-time face swap</h1> | |
| <p class="lede">Fix portrait orientation, position a square crop around the face, and export a consistent RGB PNG before uploading it as a reference in LiveFaceSwap AI. Processing stays in your browser.</p> | |
| <nav class="hero-links" aria-label="Primary links"> | |
| <a class="button-link primary" href="#tool">Prepare a portrait</a> | |
| <a class="button-link" href="https://livefaceswap.ai/?utm_source=huggingface&utm_medium=referral&utm_campaign=reference_prep" target="_blank" rel="noopener">Open LiveFaceSwap AI</a> | |
| </nav> | |
| </header> | |
| <section class="tool" id="tool" aria-labelledby="tool-title"> | |
| <div class="controls"> | |
| <div><h2 id="tool-title">Reference image prep</h2><p>Upload an authorized portrait or use the synthetic example to test the complete crop-and-export path.</p></div> | |
| <label>Portrait image<input id="file" type="file" accept="image/jpeg,image/png,image/webp" /></label> | |
| <button class="secondary" id="example" type="button">Try synthetic example</button> | |
| <label>Output size<select id="size"><option value="512">512 × 512</option><option value="768">768 × 768</option><option value="1024" selected>1024 × 1024</option></select></label> | |
| <label>Horizontal crop focus <span class="value" id="focus-x-value">0.50</span><input id="focus-x" type="range" min="0" max="1" value="0.5" step="0.01" /></label> | |
| <label>Vertical crop focus <span class="value" id="focus-y-value">0.42</span><input id="focus-y" type="range" min="0" max="1" value="0.42" step="0.01" /></label> | |
| <button id="download" type="button" disabled>Download prepared RGB PNG</button> | |
| </div> | |
| <div class="preview" id="preview" aria-live="polite"><div class="placeholder">Choose a JPG, PNG, or WebP portrait to generate a real square preview. Maximum file size: 20 MB.</div><canvas id="canvas" hidden aria-label="Prepared square portrait preview"></canvas></div> | |
| </section> | |
| <p class="privacy">Your selected image is decoded and processed on this page. It is not sent to an application server.</p> | |
| <section class="section" aria-labelledby="workflow-title"> | |
| <h2 id="workflow-title">Where this fits in the face swap workflow</h2> | |
| <p class="section-intro">This page prepares the portrait file; it does not perform identity transformation. The actual real-time face swap happens after you upload the prepared PNG to LiveFaceSwap AI.</p> | |
| <div class="workflow"> | |
| <article class="card"><div class="step">1</div><h3>Choose an authorized portrait</h3><p>Use one clear, front-facing face that you own or have permission to process.</p></article> | |
| <article class="card"><div class="step">2</div><h3>Frame the face</h3><p>Correct orientation, choose a size, and adjust the crop focus until the face is centered.</p></article> | |
| <article class="card"><div class="step">3</div><h3>Export a clean PNG</h3><p>Download a square 512, 768, or 1024 pixel RGB PNG with image metadata removed.</p></article> | |
| <article class="card"><div class="step">4</div><h3>Use it in LiveFaceSwap</h3><p>Choose Face Swap, upload the PNG under Reference, turn on your camera, and review the live output.</p></article> | |
| </div> | |
| </section> | |
| <section class="section" aria-labelledby="value-title"> | |
| <h2 id="value-title">Why prepare the reference first?</h2> | |
| <div class="benefits"> | |
| <article class="card"><h3>Predictable framing</h3><p>Move the crop across a landscape or portrait image instead of losing the intended face to an automatic center crop.</p></article> | |
| <article class="card"><h3>Consistent image format</h3><p>Normalize orientation and produce a square RGB PNG at a known size for the downstream workflow.</p></article> | |
| <article class="card"><h3>Private preprocessing</h3><p>Preview and export locally in your browser before deciding whether to use the image elsewhere.</p></article> | |
| </div> | |
| </section> | |
| <section class="section details" aria-labelledby="input-title"> | |
| <div><h2 id="input-title">Choose a useful portrait</h2><ul><li>Prefer one visible, front-facing face with open eyes and a clear facial outline.</li><li>Use even lighting and enough resolution to preserve detail after cropping.</li><li>Avoid group photos, heavy blur, extreme angles, strong shadows, and facial obstructions.</li><li>Keep the full face inside the preview; preparation reduces input issues but cannot guarantee a particular swap result.</li></ul></div> | |
| <dl class="specs"><div><dt>Input</dt><dd>One JPG, PNG, or WebP image up to 20 MB</dd></div><div><dt>Controls</dt><dd>Output size, horizontal crop focus, and vertical crop focus</dd></div><div><dt>Output</dt><dd>Square 512×512, 768×768, or 1024×1024 RGB PNG</dd></div><div><dt>Boundary</dt><dd>Reference preprocessing only; no face swap model or identity transformation runs here</dd></div></dl> | |
| </section> | |
| <section class="section" aria-labelledby="faq-title"> | |
| <h2 id="faq-title">Frequently asked questions</h2> | |
| <details><summary>Does this page perform face swapping?</summary><p>No. It prepares a portrait reference. Face swapping happens later in the LiveFaceSwap AI browser or desktop workflow.</p></details> | |
| <details><summary>Is my portrait uploaded to a server?</summary><p>No. This is a static browser utility. The selected image is decoded, cropped, resized, and exported locally on this page.</p></details> | |
| <details><summary>Which output size should I use?</summary><p>1024×1024 is a practical default when the source contains enough detail. Use 512 or 768 when you need a smaller file.</p></details> | |
| <details><summary>What do the focus sliders change?</summary><p>They move the square crop across a non-square source so you can keep the intended face centered in the exported image.</p></details> | |
| <details><summary>Can I use the output elsewhere?</summary><p>Yes. It is a standard RGB PNG and can be used in other authorized portrait workflows that accept square references.</p></details> | |
| </section> | |
| <footer> | |
| <h2>Continue with LiveFaceSwap AI</h2> | |
| <p>Open the real-time face swap workspace, read the step-by-step guide, or inspect the MIT-licensed preprocessing source.</p> | |
| <nav class="project-links" aria-label="Project links"><a class="button-link primary" href="https://livefaceswap.ai/?utm_source=huggingface&utm_medium=referral&utm_campaign=reference_prep" target="_blank" rel="noopener">LiveFaceSwap AI official website</a><a class="button-link" href="https://livefaceswap.ai/guides/live-face-swap-online?utm_source=huggingface&utm_medium=referral&utm_campaign=reference_prep" target="_blank" rel="noopener">Online face swap guide</a><a class="button-link" href="https://github.com/LiveFaceSwapAI/livefaceswap-reference-prep" target="_blank" rel="noopener">Canonical source</a></nav> | |
| <p>Only process images you own or have permission to use. Do not use portrait references to impersonate, deceive, defraud, harass, or violate another person's rights. Disclose AI-altered media when context requires it.</p> | |
| </footer> | |
| </main> | |
| <script> | |
| const fileInput = document.querySelector("#file"); | |
| const exampleButton = document.querySelector("#example"); | |
| const sizeInput = document.querySelector("#size"); | |
| const focusXInput = document.querySelector("#focus-x"); | |
| const focusYInput = document.querySelector("#focus-y"); | |
| const focusXValue = document.querySelector("#focus-x-value"); | |
| const focusYValue = document.querySelector("#focus-y-value"); | |
| const canvas = document.querySelector("#canvas"); | |
| const placeholder = document.querySelector(".placeholder"); | |
| const downloadButton = document.querySelector("#download"); | |
| const context = canvas.getContext("2d", { alpha: false }); | |
| let source = null; | |
| async function decodeImage(file) { | |
| if ("createImageBitmap" in window) return createImageBitmap(file, { imageOrientation: "from-image" }); | |
| const url = URL.createObjectURL(file); | |
| try { const image = new Image(); image.src = url; await image.decode(); return image; } | |
| finally { URL.revokeObjectURL(url); } | |
| } | |
| function render() { | |
| focusXValue.textContent = Number(focusXInput.value).toFixed(2); | |
| focusYValue.textContent = Number(focusYInput.value).toFixed(2); | |
| if (!source) return; | |
| const outputSize = Number(sizeInput.value); | |
| const width = source.width || source.naturalWidth; | |
| const height = source.height || source.naturalHeight; | |
| const side = Math.min(width, height); | |
| const left = Math.round((width - side) * Number(focusXInput.value)); | |
| const top = Math.round((height - side) * Number(focusYInput.value)); | |
| canvas.width = outputSize; | |
| canvas.height = outputSize; | |
| context.fillStyle = "#ffffff"; | |
| context.fillRect(0, 0, outputSize, outputSize); | |
| context.drawImage(source, left, top, side, side, 0, 0, outputSize, outputSize); | |
| canvas.hidden = false; | |
| placeholder.hidden = true; | |
| downloadButton.disabled = false; | |
| } | |
| fileInput.addEventListener("change", async () => { | |
| const file = fileInput.files && fileInput.files[0]; | |
| if (!file) return; | |
| if (file.size > 20 * 1024 * 1024) { alert("Please choose an image smaller than 20 MB."); fileInput.value = ""; return; } | |
| if (source && typeof source.close === "function") source.close(); | |
| source = await decodeImage(file); | |
| render(); | |
| }); | |
| exampleButton.addEventListener("click", async () => { | |
| const syntheticPortrait = `<svg xmlns="http://www.w3.org/2000/svg" width="1200" height="800" viewBox="0 0 1200 800"><defs><linearGradient id="b" x1="0" y1="0" x2="1" y2="1"><stop stop-color="#263d7a"/><stop offset="1" stop-color="#8aa9ef"/></linearGradient></defs><rect width="1200" height="800" fill="url(#b)"/><circle cx="700" cy="310" r="170" fill="#f1c6a8"/><path d="M530 310c10-150 90-210 185-210 115 0 190 86 170 225-54-58-96-94-178-98-68-3-117 24-177 83Z" fill="#29283a"/><ellipse cx="645" cy="315" rx="18" ry="12" fill="#242334"/><ellipse cx="760" cy="315" rx="18" ry="12" fill="#242334"/><path d="M665 390c31 24 69 24 100 0" fill="none" stroke="#a85e68" stroke-width="12" stroke-linecap="round"/><path d="M430 800c28-205 125-310 270-310s242 105 270 310" fill="#18274f"/><circle cx="1010" cy="150" r="70" fill="#f4d77b" opacity=".72"/></svg>`; | |
| if (source && typeof source.close === "function") source.close(); | |
| const image = new Image(); | |
| image.src = `data:image/svg+xml;charset=utf-8,${encodeURIComponent(syntheticPortrait)}`; | |
| await image.decode(); | |
| source = image; | |
| focusXInput.value = "0.58"; | |
| focusYInput.value = "0.45"; | |
| render(); | |
| }); | |
| [sizeInput, focusXInput, focusYInput].forEach((input) => input.addEventListener("input", render)); | |
| downloadButton.addEventListener("click", () => { | |
| canvas.toBlob((blob) => { if (!blob) return; const link = document.createElement("a"); link.href = URL.createObjectURL(blob); link.download = "livefaceswap-reference.png"; link.click(); setTimeout(() => URL.revokeObjectURL(link.href), 1000); }, "image/png"); | |
| }); | |
| </script> | |
| </body> | |
| </html> | |