{"id":253,"date":"2024-06-14T07:28:16","date_gmt":"2024-06-14T06:28:16","guid":{"rendered":"https:\/\/divbydev.com\/?page_id=253"},"modified":"2024-07-10T06:54:49","modified_gmt":"2024-07-10T05:54:49","slug":"background-remover","status":"publish","type":"page","link":"https:\/\/divbydev.com\/index.php\/projects-2\/background-remover\/","title":{"rendered":"Background Remover (WIP)"},"content":{"rendered":"\n<p>The Background Remover tool helps you remove the background from your images, making them transparent and ready for use in various projects.<\/p>\n\n\n\n<p>Note: This tool is still a Work In Progress\/Testing &#8211; not functional at this time. Will remove the WIP when\/if it passes testing.<\/p>\n\n\n\n<p><strong>Use Cases:<\/strong><\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>Product Photos<\/strong>: Create professional-looking product images with transparent backgrounds.<\/li>\n\n\n\n<li><strong>Graphic Design<\/strong>: Extract subjects from photos for use in collages or other designs.<\/li>\n\n\n\n<li><strong>Presentations<\/strong>: Use images without backgrounds for cleaner, more professional slides.<\/li>\n<\/ol>\n\n\n\n<div id=\"background-remover\">\n    <style>\n        \/* Reset all styles for this container *\/\n        #background-remover {\n            all: unset;\n            display: block;\n        }\n\n        \/* Reapply custom styles *\/\n        #background-remover * {\n            all: revert;\n        }\n\n        #background-remover body {\n            font-family: Arial, sans-serif;\n            display: flex;\n            justify-content: center;\n            align-items: center;\n            height: 100vh;\n            background-color: #f0f0f0;\n            margin: 0;\n            flex-direction: column;\n        }\n\n        .site-header .header-image {\n      display: flex;\n      justify-content: flex-start;\n      width: 100px;\n      max-width: 100%; \/* Ensure the logo scales properly *\/\n      height: 100px;\n     }\n\n        #background-remover .container {\n            background-color: white;\n            padding: 20px;\n            border-radius: 8px;\n            box-shadow: 0 0 10px rgba(0, 0, 0, 0.1);\n            text-align: center;\n            width: 100%;\n            max-width: 600px;\n        }\n\n        #background-remover .input-group {\n            margin: 10px 0;\n        }\n\n        #background-remover #dropArea {\n            border: 2px dashed #ccc;\n            border-radius: 8px;\n            padding: 20px;\n            cursor: pointer;\n            margin-bottom: 20px;\n        }\n\n        #background-remover #dropArea.dragover {\n            background-color: #f0f0f0;\n        }\n\n        #background-remover .canvas-wrapper {\n            position: relative;\n            display: inline-block;\n            margin-top: 20px;\n        }\n\n        #background-remover canvas {\n            border: 1px solid #ccc;\n            display: none;\n        }\n\n        #background-remover canvas#previewCanvas {\n            background-image: linear-gradient(45deg, #ccc 25%, transparent 25%), \n                            linear-gradient(135deg, #ccc 25%, transparent 25%),\n                            linear-gradient(45deg, transparent 75%, #ccc 75%), \n                            linear-gradient(135deg, transparent 75%, #ccc 75%);\n            background-size: 20px 20px;\n            background-position: 0 0, 10px 0, 10px -10px, 0px 10px;\n        }\n    <\/style>\n\n    <div class=\"container\">\n        <p>Images are processed locally in your browser and are never uploaded or saved.<br><br>Drag and drop your image here or click to upload.<\/p>\n        <div id=\"dropArea\">\n            <input type=\"file\" id=\"imageInput\" accept=\"image\/*\">\n            <p id=\"dropAreaText\">No file selected<\/p>\n        <\/div>\n        <div class=\"input-group\">\n            <button id=\"clearBtn\" style=\"display:none;\">Clear<\/button>\n            <button id=\"removeBackgroundBtn\" style=\"display:none;\">Remove Background<\/button>\n            <button id=\"removeShadowBtn\" style=\"display:none;\">Remove Shadow<\/button>\n        <\/div>\n        <div class=\"canvas-wrapper\">\n            <canvas id=\"canvas\" width=\"500\" height=\"500\"><\/canvas>\n            <div>Original Image<\/div>\n        <\/div>\n        <div class=\"canvas-wrapper\">\n            <canvas id=\"previewCanvas\" width=\"500\" height=\"500\" style=\"display:none;\"><\/canvas>\n            <div>New Image<\/div>\n        <\/div>\n        <a id=\"downloadLink\" style=\"display:none;\">Download Image<\/a>\n    <\/div>\n\n    <script>\n        document.addEventListener('DOMContentLoaded', () => {\n            console.log('Document loaded and DOM fully built');\n            const imageInput = document.getElementById('imageInput');\n            const dropArea = document.getElementById('dropArea');\n            const dropAreaText = document.getElementById('dropAreaText');\n            const clearBtn = document.getElementById('clearBtn');\n            const removeBackgroundBtn = document.getElementById('removeBackgroundBtn');\n            const removeShadowBtn = document.getElementById('removeShadowBtn');\n            const canvas = document.getElementById('canvas');\n            const previewCanvas = document.getElementById('previewCanvas');\n            const ctx = canvas.getContext('2d');\n            const previewCtx = previewCanvas.getContext('2d');\n            const downloadLink = document.getElementById('downloadLink');\n            let originalImage = null;\n\n            imageInput.addEventListener('change', handleImageUpload);\n            dropArea.addEventListener('dragover', handleDragOver);\n            dropArea.addEventListener('drop', handleDrop);\n            clearBtn.addEventListener('click', clearImage);\n            removeBackgroundBtn.addEventListener('click', removeBackground);\n            removeShadowBtn.addEventListener('click', enableShadowRemoval);\n\n            function handleImageUpload(event) {\n                console.log('File input change event');\n                const file = event.target.files[0];\n                processFile(file);\n                dropAreaText.textContent = file ? `File selected: ${file.name}` : 'No file selected';\n                clearBtn.style.display = 'inline-block';\n                removeBackgroundBtn.style.display = 'inline-block';\n                removeShadowBtn.style.display = 'inline-block';\n            }\n\n            function handleDragOver(event) {\n                event.preventDefault();\n                event.stopPropagation();\n                dropArea.classList.add('dragover');\n                console.log('Drag over event');\n            }\n\n            function handleDrop(event) {\n                event.preventDefault();\n                event.stopPropagation();\n                dropArea.classList.remove('dragover');\n                const file = event.dataTransfer.files[0];\n                processFile(file);\n                dropAreaText.textContent = file ? `File selected: ${file.name}` : 'No file selected';\n                clearBtn.style.display = 'inline-block';\n                removeBackgroundBtn.style.display = 'inline-block';\n                removeShadowBtn.style.display = 'inline-block';\n                console.log('Drop event');\n            }\n\n            function processFile(file) {\n                if (file) {\n                    const reader = new FileReader();\n                    reader.onload = function (e) {\n                        const img = new Image();\n                        img.onload = function () {\n                            originalImage = img;\n                            canvas.width = img.width;\n                            canvas.height = img.height;\n                            previewCanvas.width = img.width;\n                            previewCanvas.height = img.height;\n                            ctx.drawImage(img, 0, 0);\n                            previewCtx.clearRect(0, 0, previewCanvas.width, previewCanvas.height);\n                            previewCtx.drawImage(img, 0, 0);\n                            canvas.style.display = 'block';\n                            previewCanvas.style.display = 'none';\n                            console.log('Image processed and displayed on canvas');\n                        };\n                        img.src = e.target.result;\n                    };\n                    reader.readAsDataURL(file);\n                }\n            }\n\n            function clearImage() {\n                console.log('Clear button clicked');\n                originalImage = null;\n                canvas.width = 500;\n                canvas.height = 500;\n                previewCanvas.width = 500;\n                previewCanvas.height = 500;\n                ctx.clearRect(0, 0, canvas.width, canvas.height);\n                previewCtx.clearRect(0, 0, previewCanvas.width, previewCanvas.height);\n                dropAreaText.textContent = 'No file selected';\n                clearBtn.style.display = 'none';\n                removeBackgroundBtn.style.display = 'none';\n                removeShadowBtn.style.display = 'none';\n                downloadLink.style.display = 'none';\n                canvas.style.display = 'none';\n                previewCanvas.style.display = 'none';\n            }\n\n            function removeBackground() {\n                if (originalImage) {\n                    console.log('Remove background button clicked');\n                    const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height);\n                    const data = imageData.data;\n                    const bgColor = {\n                        r: data[0],\n                        g: data[1],\n                        b: data[2],\n                        a: data[3],\n                    };\n\n                    function isSameColor(c1, c2, tolerance = 50) {\n                        return (\n                            Math.abs(c1.r - c2.r) < tolerance &#038;&#038;\n                            Math.abs(c1.g - c2.g) < tolerance &#038;&#038;\n                            Math.abs(c1.b - c2.b) < tolerance\n                        );\n                    }\n\n                    function floodFill(x, y, targetColor, fillColor) {\n                        const stack = [[x, y]];\n                        while (stack.length > 0) {\n                            const [cx, cy] = stack.pop();\n                            const index = (cy * canvas.width + cx) * 4;\n                            const currentColor = {\n                                r: data[index],\n                                g: data[index + 1],\n                                b: data[index + 2],\n                                a: data[index + 3],\n                            };\n\n                            if (isSameColor(currentColor, targetColor) && !isSameColor(currentColor, fillColor)) {\n                                data[index] = fillColor.r;\n                                data[index + 1] = fillColor.g;\n                                data[index + 2] = fillColor.b;\n                                data[index + 3] = fillColor.a;\n\n                                if (cx > 0) stack.push([cx - 1, cy]);\n                                if (cx < canvas.width - 1) stack.push([cx + 1, cy]);\n                                if (cy > 0) stack.push([cx, cy - 1]);\n                                if (cy < canvas.height - 1) stack.push([cx, cy + 1]);\n                            }\n                        }\n                    }\n\n                    const fillColor = { r: 0, g: 0, b: 0, a: 0 };\n                    floodFill(0, 0, bgColor, fillColor);\n\n                    ctx.putImageData(imageData, 0, 0);\n\n                    \/\/ Show the preview with checkerboard pattern\n                    previewCtx.clearRect(0, 0, previewCanvas.width, previewCanvas.height);\n                    previewCtx.drawImage(canvas, 0, 0);\n                    previewCanvas.style.display = 'block';\n\n                    \/\/ Enable download link\n                    downloadLink.href = previewCanvas.toDataURL('image\/png');\n                    downloadLink.download = 'background-removed.png';\n                    downloadLink.style.display = 'inline-block';\n                    downloadLink.textContent = 'Download Image';\n                }\n            }\n\n            function enableShadowRemoval() {\n                previewCanvas.addEventListener('click', handleShadowClick);\n                console.log('Shadow removal enabled');\n            }\n\n            function handleShadowClick(event) {\n                const rect = previewCanvas.getBoundingClientRect();\n                const x = event.clientX - rect.left;\n                const y = event.clientY - rect.top;\n                removeShadow(x, y);\n                previewCanvas.removeEventListener('click', handleShadowClick);\n            }\n\n            function removeShadow(x, y) {\n                if (originalImage) {\n                    console.log('Remove shadow button clicked');\n                    const imageData = previewCtx.getImageData(0, 0, previewCanvas.width, previewCanvas.height);\n                    const data = imageData.data;\n                    const index = (Math.floor(y) * previewCanvas.width + Math.floor(x)) * 4;\n                    const targetColor = {\n                        r: data[index],\n                        g: data[index + 1],\n                        b: data[index + 2],\n                        a: data[index + 3],\n                    };\n\n                    function isSameColor(c1, c2, tolerance = 50) {\n                        return (\n                            Math.abs(c1.r - c2.r) < tolerance &#038;&#038;\n                            Math.abs(c1.g - c2.g) < tolerance &#038;&#038;\n                            Math.abs(c1.b - c2.b) < tolerance\n                        );\n                    }\n\n                    function floodFill(x, y, targetColor, fillColor) {\n                        const stack = [[x, y]];\n                        while (stack.length > 0) {\n                            const [cx, cy] = stack.pop();\n                            const index = (cy * previewCanvas.width + cx) * 4;\n                            const currentColor = {\n                                r: data[index],\n                                g: data[index + 1],\n                                b: data[index + 2],\n                                a: data[index + 3],\n                            };\n\n                            if (isSameColor(currentColor, targetColor) && !isSameColor(currentColor, fillColor)) {\n                                data[index] = fillColor.r;\n                                data[index + 1] = fillColor.g;\n                                data[index + 2] = fillColor.b;\n                                data[index + 3] = fillColor.a;\n\n                                if (cx > 0) stack.push([cx - 1, cy]);\n                                if (cx < previewCanvas.width - 1) stack.push([cx + 1, cy]);\n                                if (cy > 0) stack.push([cx, cy - 1]);\n                                if (cy < previewCanvas.height - 1) stack.push([cx, cy + 1]);\n                            }\n                        }\n                    }\n\n                    const fillColor = { r: 0, g: 0, b: 0, a: 0 };\n                    floodFill(Math.floor(x), Math.floor(y), targetColor, fillColor);\n\n                    previewCtx.putImageData(imageData, 0, 0);\n\n                    \/\/ Enable download link\n                    downloadLink.href = previewCanvas.toDataURL('image\/png');\n                    downloadLink.download = 'shadow-removed.png';\n                    downloadLink.style.display = 'inline-block';\n                    downloadLink.textContent = 'Download Image';\n                }\n            }\n        });\n    <\/script>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The Background Remover tool helps you remove the background from your images, making them transparent and ready for use in various projects. Note: This tool is still a Work In Progress\/Testing &#8211; not functional at this time. Will remove the WIP when\/if it passes testing. Use Cases: Images are processed locally in your browser and &#8230; <a title=\"Background Remover (WIP)\" class=\"read-more\" href=\"https:\/\/divbydev.com\/index.php\/projects-2\/background-remover\/\" aria-label=\"Read more about Background Remover (WIP)\">Read more<\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"parent":230,"menu_order":0,"comment_status":"closed","ping_status":"closed","template":"","meta":{"footnotes":""},"class_list":["post-253","page","type-page","status-publish"],"_links":{"self":[{"href":"https:\/\/divbydev.com\/index.php\/wp-json\/wp\/v2\/pages\/253","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/divbydev.com\/index.php\/wp-json\/wp\/v2\/pages"}],"about":[{"href":"https:\/\/divbydev.com\/index.php\/wp-json\/wp\/v2\/types\/page"}],"author":[{"embeddable":true,"href":"https:\/\/divbydev.com\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/divbydev.com\/index.php\/wp-json\/wp\/v2\/comments?post=253"}],"version-history":[{"count":63,"href":"https:\/\/divbydev.com\/index.php\/wp-json\/wp\/v2\/pages\/253\/revisions"}],"predecessor-version":[{"id":498,"href":"https:\/\/divbydev.com\/index.php\/wp-json\/wp\/v2\/pages\/253\/revisions\/498"}],"up":[{"embeddable":true,"href":"https:\/\/divbydev.com\/index.php\/wp-json\/wp\/v2\/pages\/230"}],"wp:attachment":[{"href":"https:\/\/divbydev.com\/index.php\/wp-json\/wp\/v2\/media?parent=253"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}