Spaces:
Running
Running
| <html lang="en"> | |
| <head> | |
| <meta charset="UTF-8"> | |
| <meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
| <title>Hugging Face Image Generator</title> | |
| <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css"> | |
| <style> | |
| :root { | |
| --primary-color: #ff6b6b; | |
| --secondary-color: #4ecdc4; | |
| --dark-color: #2a2a2a; | |
| --light-color: #f8f9fa; | |
| --shadow: 0 4px 6px rgba(0, 0, 0, 0.1); | |
| --transition: all 0.3s ease; | |
| } | |
| * { | |
| margin: 0; | |
| padding: 0; | |
| box-sizing: border-box; | |
| } | |
| body { | |
| font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif; | |
| line-height: 1.6; | |
| color: var(--dark-color); | |
| background: linear-gradient(135deg, #f5f7fa 0%, #c3cfe2 100%); | |
| min-height: 100vh; | |
| padding: 20px; | |
| } | |
| .container { | |
| max-width: 1000px; | |
| margin: 0 auto; | |
| padding: 20px; | |
| } | |
| header { | |
| text-align: center; | |
| margin-bottom: 30px; | |
| padding: 20px 0; | |
| border-bottom: 1px solid rgba(0, 0, 0, 0.1); | |
| } | |
| .header-content { | |
| display: flex; | |
| justify-content: space-between; | |
| align-items: center; | |
| flex-wrap: wrap; | |
| gap: 15px; | |
| } | |
| h1 { | |
| color: var(--primary-color); | |
| font-size: 2.5rem; | |
| margin-bottom: 10px; | |
| display: flex; | |
| align-items: center; | |
| gap: 10px; | |
| } | |
| .anycoder-link { | |
| color: var(--secondary-color); | |
| text-decoration: none; | |
| font-size: 0.9rem; | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| transition: var(--transition); | |
| } | |
| .anycoder-link:hover { | |
| color: var(--primary-color); | |
| transform: translateY(-2px); | |
| } | |
| .generator-card { | |
| background: white; | |
| border-radius: 15px; | |
| box-shadow: var(--shadow); | |
| padding: 30px; | |
| margin-bottom: 30px; | |
| transition: var(--transition); | |
| } | |
| .generator-card:hover { | |
| box-shadow: 0 6px 12px rgba(0, 0, 0, 0.15); | |
| } | |
| .form-group { | |
| margin-bottom: 20px; | |
| } | |
| label { | |
| display: block; | |
| margin-bottom: 8px; | |
| font-weight: 600; | |
| color: var(--dark-color); | |
| } | |
| input[type="text"], | |
| textarea, | |
| select { | |
| width: 100%; | |
| padding: 12px 15px; | |
| border: 2px solid #e0e0e0; | |
| border-radius: 8px; | |
| font-size: 1rem; | |
| transition: var(--transition); | |
| background-color: #f8f9fa; | |
| } | |
| input[type="text"]:focus, | |
| textarea:focus, | |
| select:focus { | |
| outline: none; | |
| border-color: var(--primary-color); | |
| background-color: white; | |
| } | |
| textarea { | |
| min-height: 120px; | |
| resize: vertical; | |
| } | |
| .settings-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fit, minmax(200px, 1fr)); | |
| gap: 20px; | |
| margin-bottom: 20px; | |
| } | |
| .generate-btn { | |
| background: linear-gradient(45deg, var(--primary-color), #ff8e53); | |
| color: white; | |
| border: none; | |
| padding: 12px 30px; | |
| font-size: 1rem; | |
| font-weight: 600; | |
| border-radius: 8px; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 8px; | |
| width: 100%; | |
| } | |
| .generate-btn:hover { | |
| transform: translateY(-2px); | |
| box-shadow: 0 4px 8px rgba(255, 107, 107, 0.3); | |
| } | |
| .generate-btn:disabled { | |
| background: #cccccc; | |
| cursor: not-allowed; | |
| transform: none; | |
| } | |
| .results-section { | |
| background: white; | |
| border-radius: 15px; | |
| box-shadow: var(--shadow); | |
| padding: 30px; | |
| } | |
| .results-grid { | |
| display: grid; | |
| grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); | |
| gap: 20px; | |
| margin-top: 20px; | |
| } | |
| .image-card { | |
| background: #f8f9fa; | |
| border-radius: 10px; | |
| overflow: hidden; | |
| transition: var(--transition); | |
| position: relative; | |
| } | |
| .image-card:hover { | |
| transform: translateY(-5px); | |
| box-shadow: 0 6px 12px rgba(0, 0, 0, 0.1); | |
| } | |
| .generated-image { | |
| width: 100%; | |
| height: 250px; | |
| object-fit: cover; | |
| display: block; | |
| } | |
| .image-actions { | |
| padding: 10px; | |
| display: flex; | |
| justify-content: space-between; | |
| background: white; | |
| } | |
| .download-btn { | |
| background: var(--secondary-color); | |
| color: white; | |
| border: none; | |
| padding: 8px 12px; | |
| border-radius: 5px; | |
| cursor: pointer; | |
| transition: var(--transition); | |
| display: flex; | |
| align-items: center; | |
| gap: 5px; | |
| } | |
| .download-btn:hover { | |
| background: #3aa89d; | |
| } | |
| .loading { | |
| display: none; | |
| text-align: center; | |
| padding: 20px; | |
| } | |
| .loading.active { | |
| display: block; | |
| } | |
| .spinner { | |
| border: 4px solid rgba(0, 0, 0, 0.1); | |
| border-radius: 50%; | |
| border-top: 4px solid var(--primary-color); | |
| width: 40px; | |
| height: 40px; | |
| animation: spin 1s linear infinite; | |
| margin: 0 auto 10px; | |
| } | |
| @keyframes spin { | |
| 0% { transform: rotate(0deg); } | |
| 100% { transform: rotate(360deg); } | |
| } | |
| .status-message { | |
| text-align: center; | |
| padding: 15px; | |
| border-radius: 8px; | |
| margin: 15px 0; | |
| display: none; | |
| } | |
| .success { | |
| background-color: #d4edda; | |
| color: #155724; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 8px; | |
| } | |
| .error { | |
| background-color: #f8d7da; | |
| color: #721c24; | |
| display: flex; | |
| align-items: center; | |
| justify-content: center; | |
| gap: 8px; | |
| } | |
| .api-info { | |
| background: #e7f3ff; | |
| border-left: 4px solid var(--secondary-color); | |
| padding: 15px; | |
| margin: 20px 0; | |
| border-radius: 0 8px 8px 0; | |
| } | |
| .api-info h3 { | |
| color: var(--secondary-color); | |
| margin-bottom: 10px; | |
| } | |
| .api-info p { | |
| margin-bottom: 5px; | |
| } | |
| .api-info code { | |
| background: rgba(0, 0, 0, 0.05); | |
| padding: 2px 5px; | |
| border-radius: 3px; | |
| font-family: monospace; | |
| } | |
| @media (max-width: 768px) { | |
| .header-content { | |
| flex-direction: column; | |
| text-align: center; | |
| } | |
| h1 { | |
| font-size: 2rem; | |
| } | |
| .settings-grid { | |
| grid-template-columns: 1fr; | |
| } | |
| .results-grid { | |
| grid-template-columns: 1fr; | |
| } | |
| } | |
| @media (max-width: 480px) { | |
| body { | |
| padding: 10px; | |
| } | |
| .container { | |
| padding: 10px; | |
| } | |
| .generator-card, .results-section { | |
| padding: 20px; | |
| } | |
| h1 { | |
| font-size: 1.8rem; | |
| } | |
| } | |
| </style> | |
| </head> | |
| <body> | |
| <div class="container"> | |
| <header> | |
| <div class="header-content"> | |
| <h1> | |
| <i class="fas fa-robot"></i> | |
| Hugging Face Image Generator | |
| </h1> | |
| <a href="https://huggingface.co/spaces/akhaliq/anycoder" class="anycoder-link" target="_blank"> | |
| <i class="fas fa-code"></i> Built with anycoder | |
| </a> | |
| </div> | |
| </header> | |
| <div class="generator-card"> | |
| <h2>Generate Images with AI</h2> | |
| <p>Enter a prompt and let the AI create amazing images for you!</p> | |
| <div class="api-info"> | |
| <h3>⚠️ Important Note</h3> | |
| <p>This demo uses the Hugging Face API. To make it work:</p> | |
| <ol> | |
| <li>You need to <a href="https://huggingface.co/settings/tokens" target="_blank">create an API token</a> on Hugging Face</li> | |
| <li>Replace <code>YOUR_API_TOKEN</code> in the JavaScript code with your actual token</li> | |
| <li>For security, in a production app, you should call the API from your backend</li> | |
| </ol> | |
| </div> | |
| <form id="imageGenerator"> | |
| <div class="form-group"> | |
| <label for="prompt">Prompt</label> | |
| <textarea id="prompt" placeholder="Describe the image you want to generate (e.g., 'a futuristic city at sunset with flying cars')" required></textarea> | |
| </div> | |
| <div class="settings-grid"> | |
| <div class="form-group"> | |
| <label for="model">Model</label> | |
| <select id="model"> | |
| <option value="stabilityai/stable-diffusion-2">Stable Diffusion 2</option> | |
| <option value="runwayml/stable-diffusion-v1-5">Stable Diffusion 1.5</option> | |
| <option value="CompVis/stable-diffusion-v1-4">Stable Diffusion 1.4</option> | |
| </select> | |
| </div> | |
| <div class="form-group"> | |
| <label for="negativePrompt">Negative Prompt (optional)</label> | |
| <input type="text" id="negativePrompt" placeholder="Things to exclude from the image"> | |
| </div> | |
| <div class="form-group"> | |
| <label for="numImages">Number of Images</label> | |
| <select id="numImages"> | |
| <option value="1">1</option> | |
| <option value="2">2</option> | |
| <option value="3">3</option> | |
| <option value="4">4</option> | |
| </select> | |
| </div> | |
| <div class="form-group"> | |
| <label for="guidanceScale">Guidance Scale</label> | |
| <select id="guidanceScale"> | |
| <option value="7.5">7.5 (Default)</option> | |
| <option value="5">5 (Less creative)</option> | |
| <option value="10">10 (More creative)</option> | |
| <option value="15">15 (Very creative)</option> | |
| </select> | |
| </div> | |
| <div class="form-group"> | |
| <label for="numInferenceSteps">Inference Steps</label> | |
| <select id="numInferenceSteps"> | |
| <option value="50">50 (Default)</option> | |
| <option value="25">25 (Faster)</option> | |
| <option value="75">75 (Better quality)</option> | |
| <option value="100">100 (Best quality)</option> | |
| </select> | |
| </div> | |
| </div> | |
| <button type="submit" class="generate-btn"> | |
| <i class="fas fa-magic"></i> Generate Images | |
| </button> | |
| </form> | |
| <div class="loading" id="loading"> | |
| <div class="spinner"></div> | |
| <p>Generating your images... This may take a moment</p> | |
| </div> | |
| <div class="status-message" id="statusMessage"></div> | |
| </div> | |
| <div class="results-section"> | |
| <h2>Generated Images</h2> | |
| <p>Your AI-generated images will appear here</p> | |
| <div class="results-grid" id="resultsGrid"> | |
| <!-- Generated images will appear here --> | |
| </div> | |
| </div> | |
| </div> | |
| <script> | |
| document.addEventListener('DOMContentLoaded', function() { | |
| const form = document.getElementById('imageGenerator'); | |
| const resultsGrid = document.getElementById('resultsGrid'); | |
| const loading = document.getElementById('loading'); | |
| const statusMessage = document.getElementById('statusMessage'); | |
| const generateBtn = form.querySelector('.generate-btn'); | |
| form.addEventListener('submit', async function(e) { | |
| e.preventDefault(); | |
| // Clear previous results and messages | |
| resultsGrid.innerHTML = ''; | |
| statusMessage.style.display = 'none'; | |
| statusMessage.className = 'status-message'; | |
| // Show loading state | |
| loading.classList.add('active'); | |
| generateBtn.disabled = true; | |
| generateBtn.textContent = 'Generating...'; | |
| // Get form values | |
| const prompt = document.getElementById('prompt').value; | |
| const model = document.getElementById('model').value; | |
| const negativePrompt = document.getElementById('negativePrompt').value; | |
| const numImages = parseInt(document.getElementById('numImages').value); | |
| const guidanceScale = parseFloat(document.getElementById('guidanceScale').value); | |
| const numInferenceSteps = parseInt(document.getElementById('numInferenceSteps').value); | |
| try { | |
| // Replace with your actual Hugging Face API token | |
| const API_TOKEN = 'YOUR_API_TOKEN'; | |
| const API_URL = `https://api-inference.huggingface.co/models/${model}`; | |
| // Prepare the request payload | |
| const payload = { | |
| inputs: prompt, | |
| options: { | |
| wait_for_model: true | |
| } | |
| }; | |
| // Add optional parameters if they have values | |
| if (negativePrompt) { | |
| payload.parameters = { | |
| negative_prompt: negativePrompt, | |
| guidance_scale: guidanceScale, | |
| num_inference_steps: numInferenceSteps, | |
| num_images_per_prompt: numImages | |
| }; | |
| } else { | |
| payload.parameters = { | |
| guidance_scale: guidanceScale, | |
| num_inference_steps: numInferenceSteps, | |
| num_images_per_prompt: numImages | |
| }; | |
| } | |
| // Make the API request | |
| const response = await fetch(API_URL, { | |
| method: 'POST', | |
| headers: { | |
| 'Content-Type': 'application/json', | |
| 'Authorization': `Bearer ${API_TOKEN}` | |
| }, | |
| body: JSON.stringify(payload) | |
| }); | |
| if (!response.ok) { | |
| throw new Error(`API request failed with status ${response.status}`); | |
| } | |
| const blob = await response.blob(); | |
| const imageUrl = URL.createObjectURL(blob); | |
| // Display the generated image | |
| displayImage(imageUrl); | |
| // Show success message | |
| showStatusMessage('Images generated successfully!', 'success'); | |
| } catch (error) { | |
| console.error('Error generating image:', error); | |
| showStatusMessage(`Error: ${error.message}`, 'error'); | |
| } finally { | |
| // Hide loading state | |
| loading.classList.remove('active'); | |
| generateBtn.disabled = false; | |
| generateBtn.innerHTML = '<i class="fas fa-magic"></i> Generate Images'; | |
| } | |
| }); | |
| function displayImage(imageUrl) { | |
| // Clear previous results | |
| resultsGrid.innerHTML = ''; | |
| // Create image card | |
| const imageCard = document.createElement('div'); | |
| imageCard.className = 'image-card'; | |
| const img = document.createElement('img'); | |
| img.src = imageUrl; | |
| img.className = 'generated-image'; | |
| img.alt = 'AI Generated Image'; | |
| const actions = document.createElement('div'); | |
| actions.className = 'image-actions'; | |
| const downloadBtn = document.createElement('button'); | |
| downloadBtn.className = 'download-btn'; | |
| downloadBtn.innerHTML = '<i class="fas fa-download"></i> Download'; | |
| downloadBtn.addEventListener('click', () => { | |
| const link = document.createElement('a'); | |
| link.href = imageUrl; | |
| link.download = 'ai-generated-image.png'; | |
| document.body.appendChild(link); | |
| link.click(); | |
| document.body.removeChild(link); | |
| }); | |
| actions.appendChild(downloadBtn); | |
| imageCard.appendChild(img); | |
| imageCard.appendChild(actions); | |
| resultsGrid.appendChild(imageCard); | |
| } | |
| function showStatusMessage(message, type) { | |
| statusMessage.textContent = message; | |
| statusMessage.className = `status-message ${type}`; | |
| statusMessage.style.display = 'block'; | |
| // Hide message after 5 seconds | |
| setTimeout(() => { | |
| statusMessage.style.display = 'none'; | |
| }, 5000); | |
| } | |
| }); | |
| </script> | |
| </body> | |
| </html> |