You've selected:
Description:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Image to SVG Outline with Line Control</title> <style> body { font-family: Arial, sans-serif; margin: 20px; } .container { display: flex; flex-direction: column; align-items: center; } img, svg { max-width: 100%; margin-top: 20px; } .buttons, .controls { margin-top: 20px; } </style> </head> <body> <div class="container"> <h1>Upload an Image to Convert to SVG Outline</h1> <input type="file" id="upload" accept="image/*"> <!-- Controls for line thickness, sensitivity, and tracing direction --> <div class="controls"> <label for="lineThickness">Line Thickness: </label> <input type="range" id="lineThickness" min="1" max="10" value="1"> <span id="lineThicknessValue">1</span> px <br><br> <label for="sensitivity">Sensitivity (Brightness Threshold): </label> <input type="range" id="sensitivity" min="0" max="255" value="128"> <span id="sensitivityValue">128</span> <br><br> <label for="traceMode">Trace Mode: </label> <select id="traceMode"> <option value="inside">Inside</option> <option value="outside">Outside</option> </select> </div> <canvas id="canvas" style="display:none;"></canvas> <div id="output"></div> <div class="buttons"> <button id="downloadSvg" style="display:none;">Download SVG</button> </div> </div> <script src="https://cdnjs.cloudflare.com/ajax/libs/svg.js/3.1.1/svg.min.js"></script> <script> let lineThickness = 1; let sensitivity = 128; let traceMode = 'inside'; // Default mode // Update line thickness document.getElementById('lineThickness').addEventListener('input', function() { lineThickness = this.value; document.getElementById('lineThicknessValue').textContent = lineThickness; }); // Update sensitivity document.getElementById('sensitivity').addEventListener('input', function() { sensitivity = this.value; document.getElementById('sensitivityValue').textContent = sensitivity; }); // Update trace mode (inside or outside) document.getElementById('traceMode').addEventListener('change', function() { traceMode = this.value; }); // Handle file upload and image processing document.getElementById('upload').addEventListener('change', function(event) { const file = event.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = function(e) { const img = new Image(); img.src = e.target.result; img.onload = function() { processImage(img); }; }; reader.readAsDataURL(file); }); // Process image and generate SVG function processImage(image) { const canvas = document.getElementById('canvas'); const ctx = canvas.getContext('2d'); // Set canvas size to match image canvas.width = image.width; canvas.height = image.height; // Draw the image on canvas ctx.drawImage(image, 0, 0); // Get image data const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height); const data = imageData.data; // Convert image to grayscale for edge detection for (let i = 0; i < data.length; i += 4) { const grayscale = data[i] * 0.3 + data[i + 1] * 0.59 + data[i + 2] * 0.11; data[i] = grayscale; // Red data[i + 1] = grayscale; // Green data[i + 2] = grayscale; // Blue } ctx.putImageData(imageData, 0, 0); // Apply edge detection const edges = sobelEdgeDetection(imageData, canvas.width, canvas.height); ctx.putImageData(edges, 0, 0); // Create SVG based on edge lines generateSVGFromEdges(edges, canvas.width, canvas.height); } // Sobel edge detection algorithm function sobelEdgeDetection(imageData, width, height) { const grayscale = imageData.data; const sobelData = []; const kernelX = [ [-1, 0, 1], [-2, 0, 2], [-1, 0, 1] ]; const kernelY = [ [-1, -2, -1], [0, 0, 0], [1, 2, 1] ]; for (let y = 0; y < height; y++) { for (let x = 0; x < width; x++) { const pixelX = ( (kernelX[0][0] * getPixel(grayscale, x - 1, y - 1, width)) + (kernelX[0][1] * getPixel(grayscale, x, y - 1, width)) + (kernelX[0][2] * getPixel(grayscale, x + 1, y - 1, width)) + (kernelX[1][0] * getPixel(grayscale, x - 1, y, width)) + (kernelX[1][2] * getPixel(grayscale, x + 1, y, width)) + (kernelX[2][0] * getPixel(grayscale, x - 1, y + 1, width)) + (kernelX[2][1] * getPixel(grayscale, x, y + 1, width)) + (kernelX[2][2] * getPixel(grayscale, x + 1, y + 1, width)) ); const pixelY = ( (kernelY[0][0] * getPixel(grayscale, x - 1, y - 1, width)) + (kernelY[0][1] * getPixel(grayscale, x, y - 1, width)) + (kernelY[0][2] * getPixel(grayscale, x + 1, y - 1, width)) + (kernelY[1][0] * getPixel(grayscale, x - 1, y, width)) + (kernelY[1][2] * getPixel(grayscale, x + 1, y, width)) + (kernelY[2][0] * getPixel(grayscale, x - 1, y + 1, width)) + (kernelY[2][1] * getPixel(grayscale, x, y + 1, width)) + (kernelY[2][2] * getPixel(grayscale, x + 1, y + 1, width)) ); const magnitude = Math.sqrt((pixelX * pixelX) + (pixelY * pixelY)) >>> 0; const index = (y * width + x) * 4; sobelData[index] = magnitude; sobelData[index + 1] = magnitude; sobelData[index + 2] = magnitude; sobelData[index + 3] = 255; // Alpha } } const newImageData = new ImageData(new Uint8ClampedArray(sobelData), width, height); return newImageData; } // Get pixel data at a specific location function getPixel(data, x, y, width) { if (x < 0 || x >= width || y < 0 || y >= width) { return 0; } const index = (y * width + x) * 4; return data[index]; } // Generate SVG from the edges detected function generateSVGFromEdges(edgeData, width, height) { const svg = SVG().size(width, height); for (let y = 0; y < height; y += 2) { for (let x = 0; x < width; x += 2) { const index = (y * width + x) * 4; const color = edgeData.data[index]; if (traceMode === 'inside' && color > sensitivity) { svg.circle(lineThickness).move(x, y).fill('#000'); // Trace inside the object } else if (traceMode === 'outside' && color < sensitivity) { svg.circle(lineThickness).move(x, y).fill('#000'); // Trace outside the object } } } // Output SVG document.getElementById('output').innerHTML = ''; document.getElementById('output').appendChild(svg.node); // Enable download button const svgData = svg.svg(); const blob = new Blob([svgData], { type: 'image/svg+xml' }); const url = URL.createObjectURL(blob); const downloadButton = document.getElementById('downloadSvg'); downloadButton.href = url; downloadButton.download = 'vectorized_image.svg'; downloadButton.style.display = 'inline-block'; } </script> </body> </html>
*Please don't hesitate to reach out to us for any additional requirements or inquiries you may have. We welcome the opportunity to assist you further
Successfully orchestrated collaboration within sizable teams, navigating through challenges to deliver projects with precision under tight deadlines.
Modules Achievements: Earned Certificates from Brainster Academy.
Brainster Academy Certificate
Robust and Versatile Web Applications Catering to a Variety of Customer Requirements.
Backend projects