jueves, junio 12, 2025
spot_img

¡Escucha la radio!

¡Escucha Candela Zacapu aquí!

    <!DOCTYPE html>
    <html lang="es">
    <head>
      <meta charset="UTF-8">
      <meta name="viewport" content="width=device-width, initial-scale=1.0">
      <title>Generador de Imágenes Purépecha</title>
      <!-- Carga de Tailwind CSS desde CDN -->
      <script src="https://cdn.tailwindcss.com"></script>
      <!-- Carga de React y ReactDOM desde CDN -->
      <script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
      <script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
      <!-- Carga de Babel para transformar JSX en el navegador -->
      <script src="https://unpkg.com/@babel/standalone/babel.min.js"></script>
      <!-- Fuente Inter para una mejor estética -->
      <link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700;800&display=swap" rel="stylesheet">
      <style>
        body {
          font-family: 'Inter', sans-serif;
        }
      </style>
    </head>
    <body class="bg-gradient-to-br from-purple-100 to-indigo-200 min-h-screen flex items-center justify-center p-4">
      <div id="root" class="w-full max-w-xl"></div>
    
      <script type="text/babel">
        // Main App component
        function App() {
          const [prompt, setPrompt] = React.useState('');
          const [imageUrl, setImageUrl] = React.useState('');
          const [loading, setLoading] = React.useState(false);
          const [error, setError] = React.useState('');
    
          // Function to generate the image
          const generateImage = async () => {
            setLoading(true);
            setImageUrl('');
            setError('');
    
            // Construct the payload for the image generation API
            const payload = {
              instances: { prompt: prompt },
              parameters: { "sampleCount": 1 }
            };
    
            // API key for the image generation model (will be provided at runtime)
            // DO NOT EDIT THIS LINE: The API key is automatically provided by the environment.
            const apiKey = "";
            // API URL for imagen-3.0-generate-002
            const apiUrl = `https://generativelanguage.googleapis.com/v1beta/models/imagen-3.0-generate-002:predict?key=${apiKey}`;
    
            try {
              // Make the API call
              const response = await fetch(apiUrl, {
                method: 'POST',
                headers: { 'Content-Type': 'application/json' },
                body: JSON.stringify(payload)
              });
    
              // Parse the response
              const result = await response.json();
    
              // Check if image generation was successful
              if (result.predictions && result.predictions.length > 0 && result.predictions[0].bytesBase64Encoded) {
                // Set the generated image URL
                setImageUrl(`data:image/png;base64,${result.predictions[0].bytesBase64Encoded}`);
              } else {
                setError('No se pudo generar la imagen. Intenta de nuevo.');
                console.error('Error in API response:', result);
              }
            } catch (e) {
              console.error('Error al generar la imagen:', e);
              setError('Ocurrió un error al conectar con el servicio. Por favor, intenta de nuevo.');
            } finally {
              setLoading(false);
            }
          };
    
          return (
            <div className="flex flex-col items-center justify-center p-4 text-gray-800">
              <header className="mb-8 text-center">
                <h1 className="text-5xl font-extrabold text-indigo-800 mb-4 tracking-tight leading-tight">
                  Generador de Imágenes
                </h1>
                <p className="text-xl text-indigo-600 max-w-2xl mx-auto">
                  Crea imágenes impresionantes con solo una descripción.
                </p>
              </header>
    
              <main className="w-full bg-white rounded-3xl shadow-2xl p-8 flex flex-col items-center border border-indigo-200">
                <div className="w-full mb-6">
                  <label htmlFor="prompt-input" className="block text-lg font-semibold text-gray-700 mb-2">
                    Describe la imagen que deseas:
                  </label>
                  <textarea
                    id="prompt-input"
                    className="w-full p-4 border border-gray-300 rounded-xl focus:ring-4 focus:ring-indigo-300 focus:border-indigo-500 transition-all duration-300 ease-in-out resize-none text-lg"
                    rows="4"
                    placeholder="Una persona purépecha tomándose una selfie en el palacio, ubicado en La Crucita en Zacapu, Michoacán"
                    value={prompt}
                    onChange={(e) => setPrompt(e.target.value)}
                  ></textarea>
                </div>
    
                <button
                  onClick={generateImage}
                  disabled={loading || !prompt.trim()}
                  className={`w-full py-4 px-6 rounded-xl text-xl font-bold transition-all duration-300 ease-in-out transform
                    ${loading || !prompt.trim()
                      ? 'bg-indigo-300 text-indigo-100 cursor-not-allowed'
                      : 'bg-indigo-600 hover:bg-indigo-700 text-white shadow-lg hover:shadow-xl hover:scale-105 active:scale-95'
                    }`}
                >
                  {loading ? (
                    <div className="flex items-center justify-center">
                      <svg className="animate-spin -ml-1 mr-3 h-6 w-6 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
                        <circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
                        <path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
                      </svg>
                      Generando...
                    </div>
                  ) : (
                    'Generar Imagen'
                  )}
                </button>
    
                {error && (
                  <p className="mt-6 text-red-600 bg-red-100 p-3 rounded-lg border border-red-300 text-center w-full">
                    {error}
                  </p>
                )}
    
                {imageUrl && (
                  <div className="mt-8 w-full">
                    <h2 className="text-2xl font-bold text-gray-800 mb-4 text-center">Tu Imagen Generada:</h2>
                    <div className="bg-gray-50 p-2 rounded-2xl shadow-inner border border-gray-200">
                      <img
                        src={imageUrl}
                        alt="Imagen generada"
                        className="w-full h-auto rounded-xl object-cover shadow-md"
                        onError={(e) => { e.target.onerror = null; e.target.src = 'https://placehold.co/600x400/CCCCCC/333333?text=Error+al+cargar+imagen'; }}
                      />
                    </div>
                  </div>
                )}
              </main>
    
              <footer className="mt-12 text-center text-gray-600">
                <p className="text-sm">
                  Impulsado por el modelo de generación de imágenes de Google.
                </p>
              </footer>
            </div>
          );
        }
    
        // Render the React application
        const container = document.getElementById('root');
        const root = ReactDOM.createRoot(container);
        root.render(<App />);
      </script>
    </body>
    </html>

    ¡Síguenos en Tik Tok!

    Noticias Relacionadas

    Lotificación en el Predio Rústico Denominado Mesa de Púcuaro

    En cumplimiento con lo establecido en el artículo 34 de la Ley General del Equilibrio Ecológico y la Protección al Ambiente, se informa al...

    Últimas noticias

    ¡Suscríbete!

    -Nunca pierdas nuestras notas

    -Recibe contenido exclusivo

    Últimas noticias

    DEJA UNA RESPUESTA

    Por favor ingrese su comentario!
    Por favor ingrese su nombre aquí