| | <div class="ai-tool-container"> |
| | <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/KaTeX/0.13.11/katex.min.css"> |
| | <link href="https://fonts.googleapis.com/css2?family=Barlow+Condensed:wght@100&display=swap" rel="stylesheet"> |
| | <div class="container"> |
| | <h3>Digitoon | Image to cartoon with digital painting </h3> |
| | <form id="remakeai-form"> |
| | <div class="form-group"> |
| | <label for="file" class="custom-file-upload"> |
| | <i class="fa fa-cloud-upload"></i> Upload Image |
| | </label> |
| | <input type="file" id="file" name="file" required> |
| | <span id="file-name"></span> |
| | </div> |
| |
|
| | <div class="form-group"> |
| | <select id="styleSelect"style="display: none;" required> |
| | <option value="AnimeGANv3_USA">Select Style</option> |
| | |
| | </select> |
| | <label for="faceCheckbox">Face Only?</label> |
| | <input type="checkbox" id="faceCheckbox"> |
| | </div> |
| |
|
| | <button type="submit" class="btn-submit">Submit</button> |
| | </form> |
| | <div class="result"></div> |
| | <div class="progress-container"> |
| | <div class="progress-bar" id="progress-bar"></div> |
| | </div> |
| | </div> |
| | </div> |
| | |
| |
|
| |
|
| |
|
| |
|
| |
|
| | |
| |
|
| | <script> |
| | document.addEventListener("DOMContentLoaded", function() { |
| | const form = document.getElementById("remakeai-form"); |
| | const fileInput = document.getElementById('file'); |
| | const fileNameSpan = document.getElementById('file-name'); |
| | const progressBar = document.getElementById('progress-bar'); |
| | const progressContainer = document.querySelector('.progress-container'); |
| | const resultDiv = document.querySelector(".result"); |
| | |
| | let simulatedProgressInterval; |
| | let simulatedProgress = 0; |
| | |
| | fileInput.addEventListener('change', function() { |
| | fileNameSpan.textContent = this.files[0].name; |
| | }); |
| | |
| | form.addEventListener("submit", async function(event) { |
| | event.preventDefault(); |
| | |
| | const file = fileInput.files[0]; |
| | const compressedFile = await compressImage(file); |
| | |
| | const formData = new FormData(); |
| | formData.append('file', compressedFile, file.name); |
| | |
| | const styleSelect = document.getElementById("styleSelect"); |
| | const faceCheckbox = document.getElementById("faceCheckbox"); |
| | const style = styleSelect.value; |
| | const if_face = faceCheckbox.checked ? "Yes" : "No"; |
| | formData.append('Style', style); |
| | formData.append('if_face', if_face); |
| | |
| | |
| | progressBar.style.width = '0%'; |
| | progressContainer.style.display = 'block'; |
| | simulatedProgress = 0; |
| | |
| | |
| | resultDiv.innerHTML = ''; |
| | |
| | const xhr = new XMLHttpRequest(); |
| | xhr.open("POST", "/inference/", true); |
| | xhr.responseType = 'blob'; |
| | |
| | xhr.upload.onprogress = function(event) { |
| | if (event.lengthComputable) { |
| | const percentComplete = (event.loaded / event.total) * 100; |
| | updateProgressBar(percentComplete); |
| | } |
| | }; |
| | |
| | xhr.onloadstart = function() { |
| | |
| | simulateBackendProcessingProgress(); |
| | }; |
| | |
| | xhr.onload = function() { |
| | clearInterval(simulatedProgressInterval); |
| | if (xhr.status === 200) { |
| | const resultBlob = xhr.response; |
| | const resultURL = URL.createObjectURL(resultBlob); |
| | |
| | const originalURL = URL.createObjectURL(file); |
| | |
| | |
| | console.log("Original URL:", originalURL); |
| | console.log("Result URL:", resultURL); |
| | console.log("Result Blob:", resultBlob); |
| | |
| | resultDiv.innerHTML = ` |
| | <h2>Result</h2> |
| | <div class="result-images"> |
| | <img src="${originalURL}" alt="Original Image" class="result-image"> |
| | <span class="arrow">↓</span> |
| | <img src="${resultURL}" alt="Result Image" class="result-image"> |
| | </div> |
| | `; |
| | |
| | |
| | const downloadButton = document.createElement('a'); |
| | downloadButton.href = resultURL; |
| | downloadButton.download = 'result.jpg'; |
| | downloadButton.textContent = 'Download Result'; |
| | downloadButton.className = 'btn-download'; |
| | resultDiv.appendChild(downloadButton); |
| | |
| | updateProgressBar(100); |
| | } else { |
| | resultDiv.innerHTML = `<p class="error-message">Error: ${xhr.statusText}</p>`; |
| | updateProgressBar(0); |
| | } |
| | |
| | setTimeout(() => { |
| | progressContainer.style.display = 'none'; |
| | }, 1000); |
| | }; |
| | |
| | xhr.onerror = function() { |
| | clearInterval(simulatedProgressInterval); |
| | resultDiv.innerHTML = `<p class="error-message">Error: Network Error</p>`; |
| | updateProgressBar(0); |
| | |
| | setTimeout(() => { |
| | progressContainer.style.display = 'none'; |
| | }, 1000); |
| | }; |
| | |
| | xhr.send(formData); |
| | }); |
| | |
| | async function compressImage(file) { |
| | return new Promise((resolve, reject) => { |
| | const reader = new FileReader(); |
| | reader.onload = function(event) { |
| | const img = new Image(); |
| | img.src = event.target.result; |
| | img.onload = function() { |
| | const canvas = document.createElement('canvas'); |
| | const ctx = canvas.getContext('2d'); |
| | |
| | const maxWidth = 1000; |
| | const maxHeight = 1000; |
| | let width = img.width; |
| | let height = img.height; |
| | if (width > height) { |
| | if (width > maxWidth) { |
| | height *= maxWidth / width; |
| | width = maxWidth; |
| | } |
| | } else { |
| | if (height > maxHeight) { |
| | width *= maxHeight / height; |
| | height = maxHeight; |
| | } |
| | } |
| | |
| | canvas.width = width; |
| | canvas.height = height; |
| | |
| | ctx.drawImage(img, 0, 0, width, height); |
| | |
| | canvas.toBlob((blob) => { |
| | resolve(blob); |
| | }, 'image/jpeg', 0.7); |
| | } |
| | } |
| | |
| | reader.readAsDataURL(file); |
| | }); |
| | } |
| | |
| | function updateProgressBar(percentComplete) { |
| | progressBar.style.width = percentComplete + '%'; |
| | updateProgressBarColor(percentComplete); |
| | } |
| | |
| | function updateProgressBarColor(percentComplete) { |
| | const startColor = "#ff0000"; |
| | const endColor = "#0056b3"; |
| | const currentColor = interpolateColor(startColor, endColor, percentComplete / 100); |
| | progressBar.style.backgroundColor = currentColor; |
| | } |
| | |
| | function interpolateColor(color1, color2, factor) { |
| | const result = color1.slice(1).match(/.{2}/g).map((hex, i) => { |
| | return Math.round(parseInt(hex, 16) * (1 - factor) + parseInt(color2.slice(1).match(/.{2}/g)[i], 16) * factor); |
| | }); |
| | return `#${result.map(val => val.toString(16).padStart(2, '0')).join('')}`; |
| | } |
| | |
| | function simulateBackendProcessingProgress() { |
| | simulatedProgressInterval = setInterval(() => { |
| | simulatedProgress += 1; |
| | if (simulatedProgress < 90) { |
| | updateProgressBar(simulatedProgress); |
| | } else { |
| | clearInterval(simulatedProgressInterval); |
| | } |
| | }, 200); |
| | } |
| | }); |
| | </script> |
| |
|
| | |
| | <style> |
| | |
| | .ai-tool-container body{ |
| | font-family: 'Barlow Condensed', sans-serif; |
| | background: linear-gradient(135deg, #f5f7fa, #c3cfe2); |
| | margin: 0; |
| | padding: 0; |
| | display: flex; |
| | justify-content: center; |
| | align-items: center; |
| | height: 100vh; |
| | direction: ltr; |
| | } |
| | |
| | .ai-tool-container { |
| | background: #fff; |
| | border-radius: 10px; |
| | box-shadow: 0 10px 15px rgba(0, 0, 0, 0.1); |
| | padding: 20px; |
| | max-width: 500px; |
| | width: 100%; |
| | text-align: center; |
| | direction: ltr; |
| | } |
| | |
| | .ai-tool-container h3 { |
| | font-size: 24px; |
| | margin-bottom: 20px; |
| | color: #333; |
| | } |
| | |
| | .ai-tool-container .form-group { |
| | margin-bottom: 15px; |
| | text-align: left; |
| | } |
| | |
| | .ai-tool-container |
| | input[type="file"] { |
| | display: none; |
| | } |
| | |
| | .ai-tool-container .custom-file-upload { |
| | display: inline-block; |
| | padding: 10px 20px; |
| | cursor: pointer; |
| | background-color: #007bff; |
| | color: #fff; |
| | border-radius: 5px; |
| | transition: background 0.3s; |
| | } |
| | |
| | .ai-tool-container .custom-file-upload:hover { |
| | background-color: #0056b3; |
| | } |
| | |
| | .ai-tool-container #file-name { |
| | display: block; |
| | margin-top: 10px; |
| | font-size: 14px; |
| | color: #555; |
| | } |
| | |
| | .ai-tool-container .radio-group { |
| | display: flex; |
| | justify-content: space-around; |
| | align-items: center; |
| | } |
| | |
| | .ai-tool-container .btn-submit { |
| | background: #007bff; |
| | color: #fff; |
| | padding: 10px 20px; |
| | border: none; |
| | border-radius: 5px; |
| | cursor: pointer; |
| | transition: background 0.3s; |
| | } |
| | |
| | .ai-tool-container .btn-submit:hover { |
| | background: #0056b3; |
| | } |
| | |
| | .ai-tool-container .result { |
| | margin-top: 20px; |
| | } |
| | |
| | .ai-tool-container .result h2 { |
| | font-size: 20px; |
| | color: #333; |
| | } |
| | |
| | .ai-tool-container .result-image { |
| | max-width: 100%; |
| | border-radius: 10px; |
| | box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); |
| | transition: transform 0.3s; |
| | } |
| | |
| | .ai-tool-container .result-image:hover { |
| | transform: scale(1.05); |
| | } |
| | |
| | .ai-tool-container .error-message { |
| | color: red; |
| | font-size: 16px; |
| | } |
| | |
| | |
| | |
| | .ai-tool-container .progress-container { |
| | width: 100%; |
| | background-color: #f3f3f3; |
| | border-radius: 5px; |
| | overflow: hidden; |
| | margin-top: 20px; |
| | display: none; |
| | } |
| | |
| | .ai-tool-container .progress-bar { |
| | height: 10px; |
| | width: 0%; |
| | transition: width 0.4s ease, background-color 0.4s ease; |
| | } |
| | .ai-tool-container .result-images { |
| | display: flex; |
| | align-items: center; |
| | justify-content: center; |
| | } |
| | .ai-tool-container .result-images { |
| | display: flex; |
| | flex-direction: column; |
| | align-items: center; |
| | justify-content: center; |
| | } |
| | |
| | .ai-tool-container .result-image { |
| | max-width: 100%; |
| | max-height: 300px; |
| | border-radius: 10px; |
| | box-shadow: 0 5px 10px rgba(0, 0, 0, 0.1); |
| | transition: transform 0.3s; |
| | margin: 10px 0; |
| | } |
| | |
| | .ai-tool-container .result-image:hover { |
| | transform: scale(1.05); |
| | } |
| | |
| | .ai-tool-container .arrow { |
| | font-size: 24px; |
| | color: #333; |
| | margin: 10px 0; |
| | } |
| | |
| | .ai-tool-container .btn-download { |
| | display: inline-block; |
| | margin-top: 20px; |
| | padding: 10px 20px; |
| | background-color: #708090; |
| | color: #fff; |
| | border-radius: 5px; |
| | text-decoration: none; |
| | transition: background 0.3s; |
| | } |
| | |
| | .ai-tool-container .btn-download:hover { |
| | background-color: #218838; |
| | } |
| | </style> |
| | </div> |