Download script.js from Natkat1/magic-background-remover: direct link, hf CLI and curl.
- Browser
- Download file 7.15 kB
-
https://huggingface.co/spaces/Natkat1/magic-background-remover/resolve/main/script.js
- Command line
-
hf download hf://spaces/Natkat1/magic-background-remover/script.js
-
curl -L -o script.js https://huggingface.co/spaces/Natkat1/magic-background-remover/resolve/main/script.js
7.15 kB
| import { removeBackground } from "https://cdn.jsdelivr.net/npm/@imgly/background-removal@1.0.0/dist/index.mjs"; | |
| document.addEventListener('DOMContentLoaded', () => { | |
| const dropArea = document.getElementById('drop-area'); | |
| const fileInput = document.getElementById('file-input'); | |
| const browseBtn = document.getElementById('browse-btn'); | |
| const uploadUI = document.getElementById('upload-ui'); | |
| const processingUI = document.getElementById('processing-ui'); | |
| const originalImage = document.getElementById('original-image'); | |
| const resultImage = document.getElementById('result-image'); | |
| const downloadBtn = document.getElementById('download-btn'); | |
| const downloadSection = document.getElementById('download-section'); | |
| const progressText = document.getElementById('progress-text'); | |
| const progressBar = document.getElementById('progress-bar'); | |
| const firstRunNotice = document.getElementById('first-run-notice'); | |
| let isFirstRun = true; | |
| let processing = false; | |
| let currentFile = null; | |
| // Prevent default drag behaviors | |
| ['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => { | |
| dropArea.addEventListener(eventName, preventDefaults, false); | |
| }); | |
| function preventDefaults(e) { | |
| e.preventDefault(); | |
| e.stopPropagation(); | |
| } | |
| // Highlight drop area when item is dragged over it | |
| ['dragenter', 'dragover'].forEach(eventName => { | |
| dropArea.addEventListener(eventName, highlight, false); | |
| }); | |
| ['dragleave', 'drop'].forEach(eventName => { | |
| dropArea.addEventListener(eventName, unhighlight, false); | |
| }); | |
| function highlight() { | |
| dropArea.classList.add('highlight'); | |
| } | |
| function unhighlight() { | |
| dropArea.classList.remove('highlight'); | |
| } | |
| // Handle dropped files | |
| dropArea.addEventListener('drop', handleDrop, false); | |
| function handleDrop(e) { | |
| const dt = e.dataTransfer; | |
| const files = dt.files; | |
| if (files.length && !processing) { | |
| handleFiles(files); | |
| } | |
| } | |
| // Handle file input | |
| fileInput.addEventListener('change', function() { | |
| if (this.files.length && !processing) { | |
| handleFiles(this.files); | |
| } | |
| }); | |
| // Browse button click | |
| browseBtn.addEventListener('click', () => { | |
| fileInput.click(); | |
| }); | |
| // Handle file processing | |
| async function handleFiles(files) { | |
| const file = files[0]; | |
| if (!file.type.match('image.*')) { | |
| alert('Please select an image file'); | |
| return; | |
| } | |
| currentFile = file; | |
| processing = true; | |
| // Show original image | |
| const reader = new FileReader(); | |
| reader.onload = function(e) { | |
| originalImage.src = e.target.result; | |
| originalImage.classList.remove('hidden'); | |
| }; | |
| reader.readAsDataURL(file); | |
| // Show processing UI | |
| uploadUI.classList.add('hidden'); | |
| processingUI.classList.remove('hidden'); | |
| if (isFirstRun) { | |
| progressText.textContent = 'Loading models for the first time (20-40MB)...'; | |
| progressBar.style.width = '10%'; | |
| } else { | |
| progressText.textContent = 'Processing image...'; | |
| progressBar.style.width = '30%'; | |
| } | |
| try { | |
| // Initialize the background removal | |
| const blobURL = URL.createObjectURL(file); | |
| // Revoke the blob URL after use to prevent memory leaks | |
| setTimeout(() => URL.revokeObjectURL(blobURL), 1000); | |
| const progressCallback = (progress) => { | |
| const percent = Math.floor(progress * 100); | |
| progressBar.style.width = `${percent}%`; | |
| if (isFirstRun) { | |
| if (progress < 0.9) { | |
| progressText.textContent = `Downloading models... ${percent}%`; | |
| } else { | |
| progressText.textContent = 'Processing image...'; | |
| } | |
| } else { | |
| progressText.textContent = `Processing... ${percent}%`; | |
| } | |
| }; | |
| // Convert file to Blob URL | |
| const blob = await fetch(blobURL).then(r => r.blob()); | |
| // Use the imported removeBackground function | |
| const result = await removeBackground(blob, { | |
| progress: progressCallback, | |
| publicPath: 'https://cdn.jsdelivr.net/npm/@imgly/background-removal@1.0.0/dist/', // Required for loading models | |
| debug: true | |
| }); | |
| // Convert Blob to URL for display | |
| // Convert result to PNG if it's not already | |
| const pngBlob = await result.convertToBlob('image/png'); | |
| const resultURL = URL.createObjectURL(pngBlob); | |
| // Display result | |
| resultImage.src = resultURL; | |
| resultImage.classList.remove('hidden'); | |
| // Enable download button | |
| downloadBtn.onclick = function() { | |
| const a = document.createElement('a'); | |
| a.href = resultURL; | |
| a.download = `background-removed-${file.name}`; | |
| document.body.appendChild(a); | |
| a.click(); | |
| document.body.removeChild(a); | |
| setTimeout(() => URL.revokeObjectURL(resultURL), 100); | |
| }; | |
| downloadSection.classList.remove('hidden'); | |
| // Reset UI | |
| processing = false; | |
| uploadUI.classList.remove('hidden'); | |
| processingUI.classList.add('hidden'); | |
| if (isFirstRun) { | |
| isFirstRun = false; | |
| firstRunNotice.classList.add('hidden'); | |
| } | |
| } catch (error) { | |
| console.error('Error during background removal:', error); | |
| // Show error message | |
| progressText.textContent = `Error: ${error.message || 'Failed to process image'}`; | |
| progressBar.style.width = '0%'; | |
| progressBar.classList.add('bg-red-500'); | |
| // Show retry button | |
| const retryBtn = document.createElement('button'); | |
| retryBtn.className = 'bg-primary-500 hover:bg-primary-600 text-white font-medium py-2 px-6 rounded-lg transition-colors duration-200 mt-4'; | |
| retryBtn.textContent = 'Try Again'; | |
| retryBtn.onclick = () => { | |
| if (currentFile) { | |
| handleFiles([currentFile]); | |
| } | |
| }; | |
| processingUI.querySelector('.flex').appendChild(retryBtn); | |
| setTimeout(() => { | |
| // Reset UI if user doesn't retry | |
| processing = false; | |
| uploadUI.classList.remove('hidden'); | |
| processingUI.classList.add('hidden'); | |
| progressBar.classList.remove('bg-red-500'); | |
| if (processingUI.contains(retryBtn)) { | |
| processingUI.querySelector('.flex').removeChild(retryBtn); | |
| } | |
| }, 8000); | |
| } | |
| } | |
| }); |