CoolFace
Apppublic

admin08077/Githubgemini

sourceHugging Faceotherupdated 10mo agoView on Hugging Face
0likes
AiImageGenerator-DdG4FXBe.js.map1 linesDownload Raw Back to assets
1{"version":3,"file":"AiImageGenerator-DdG4FXBe.js","sources":["../../components/features/AiImageGenerator.tsx"],"sourcesContent":["import React, { useState, useCallback, useRef } from 'react';\nimport { generateImage, generateImageFromImageAndText } from '../../services/aiService.ts';\nimport { fileToBase64, blobToDataURL } from '../../services/fileUtils.ts';\nimport { ImageGeneratorIcon, SparklesIcon, ArrowDownTrayIcon, XMarkIcon } from '../icons.tsx';\nimport { LoadingSpinner } from '../shared/index.tsx';\n\nconst surprisePrompts = [\n    'A majestic lion wearing a crown, painted in the style of Van Gogh.',\n    'A futuristic cityscape on another planet with two moons in the sky.',\n    'A cozy, magical library inside a giant tree.',\n    'A surreal image of a ship sailing on a sea of clouds.',\n    'An astronaut riding a space-themed bicycle on the moon.',\n];\n\ninterface UploadedImage {\n    base64: string;\n    dataUrl: string;\n    mimeType: string;\n}\n\nexport const AiImageGenerator: React.FC = () => {\n    const [prompt, setPrompt] = useState<string>('A photorealistic image of a futuristic city at sunset, with flying cars.');\n    const [uploadedImage, setUploadedImage] = useState<UploadedImage | null>(null);\n    const [generatedImageUrl, setGeneratedImageUrl] = useState<string | null>(null);\n    const [isLoading, setIsLoading] = useState<boolean>(false);\n    const [error, setError] = useState<string>('');\n    const fileInputRef = useRef<HTMLInputElement>(null);\n\n    const handleGenerate = useCallback(async () => {\n        if (!prompt.trim()) {\n            setError('Please enter a prompt to generate an image.');\n            return;\n        }\n        setIsLoading(true);\n        setError('');\n        setGeneratedImageUrl(null);\n        try {\n            let resultUrl: string;\n            if (uploadedImage) {\n                resultUrl = await generateImageFromImageAndText(prompt, uploadedImage.base64, uploadedImage.mimeType);\n            } else {\n                resultUrl = await generateImage(prompt);\n            }\n            setGeneratedImageUrl(resultUrl);\n        } catch (err) {\n            const errorMessage = err instanceof Error ? err.message : 'An unknown error occurred.';\n            setError(`Failed to generate image: ${errorMessage}`);\n        } finally {\n            setIsLoading(false);\n        }\n    }, [prompt, uploadedImage]);\n\n    const handleSurpriseMe = () => {\n        const randomPrompt = surprisePrompts[Math.floor(Math.random() * surprisePrompts.length)];\n        setPrompt(randomPrompt);\n    };\n\n    const processImageBlob = async (blob: Blob) => {\n        try {\n            const [dataUrl, base64] = await Promise.all([\n                blobToDataURL(blob),\n                fileToBase64(blob as File)\n            ]);\n            setUploadedImage({ dataUrl, base64, mimeType: blob.type });\n        } catch (e) {\n            setError('Could not process the image.');\n        }\n    };\n\n    const handlePaste = useCallback(async (event: React.ClipboardEvent) => {\n        const items = event.clipboardData.items;\n        for (const item of items) {\n            if (item.type.indexOf('image') !== -1) {\n                const blob = item.getAsFile();\n                if (blob) {\n                    await processImageBlob(blob);\n                    return;\n                }\n            }\n        }\n    }, []);\n\n    const handleFileChange = async (event: React.ChangeEvent<HTMLInputElement>) => {\n        const file = event.target.files?.[0];\n        if (file) {\n            await processImageBlob(file);\n        }\n    };\n    \n    const handleDownload = () => {\n        if (!generatedImageUrl) return;\n        const link = document.createElement('a');\n        link.href = generatedImageUrl;\n        link.download = `${prompt.slice(0, 30).replace(/\\s/g, '_')}.png`;\n        document.body.appendChild(link);\n        link.click();\n        document.body.removeChild(link);\n    }\n\n    return (\n        <div className=\"h-full flex flex-col p-4 sm:p-6 lg:p-8 text-text-primary\">\n            <header className=\"mb-6\">\n                <h1 className=\"text-3xl font-bold flex items-center\">\n                    <ImageGeneratorIcon />\n                    <span className=\"ml-3\">AI Image Generator</span>\n                </h1>\n                <p className=\"text-text-secondary mt-1\">Generate images from text, or provide an image for inspiration.</p>\n            </header>\n            \n            <div className=\"flex-grow grid grid-cols-1 lg:grid-cols-2 gap-6 min-h-0\">\n                {/* Left Column: Inputs */}\n                <div className=\"flex flex-col gap-4\">\n                    <div>\n                        <label htmlFor=\"prompt-input\" className=\"text-sm font-medium text-text-secondary\">Your Prompt</label>\n                        <textarea\n                            id=\"prompt-input\"\n                            value={prompt}\n                            onChange={(e) => setPrompt(e.target.value)}\n                            placeholder=\"e.g., A cute cat wearing a wizard hat\"\n                            className=\"w-full p-3 mt-1 rounded-md bg-surface border border-border focus:ring-2 focus:ring-primary focus:outline-none resize-y\"\n                            rows={3}\n                        />\n                    </div>\n                    \n                    <div className=\"flex flex-col flex-grow min-h-[200px]\">\n                         <label className=\"text-sm font-medium text-text-secondary mb-1\">Inspiration Image (Optional)</label>\n                         <div onPaste={handlePaste} className=\"relative flex-grow flex flex-col items-center justify-center bg-surface p-4 rounded-lg border-2 border-dashed border-border focus:outline-none focus:border-primary\" tabIndex={0}>\n                            {uploadedImage ? (\n                                <>\n                                    <img src={uploadedImage.dataUrl} alt=\"Uploaded content\" className=\"max-w-full max-h-full object-contain rounded-md shadow-lg\" />\n                                    <button onClick={() => setUploadedImage(null)} className=\"absolute top-2 right-2 p-1 bg-black/30 text-white rounded-full hover:bg-black/50\"><XMarkIcon /></button>\n                                </>\n                            ) : (\n                                <div className=\"text-center text-text-secondary\">\n                                    <h2 className=\"text-lg font-bold text-text-primary\">Paste an image here</h2>\n                                    <p className=\"text-sm\">(Cmd/Ctrl + V)</p>\n                                    <p className=\"text-xs my-1\">or</p>\n                                    <button onClick={() => fileInputRef.current?.click()} className=\"text-sm font-semibold text-primary hover:underline\">Upload File</button>\n                                    <input type=\"file\" ref={fileInputRef} onChange={handleFileChange} accept=\"image/*\" className=\"hidden\"/>\n                                </div>\n                            )}\n                         </div>\n                    </div>\n                    \n                    <div className=\"flex gap-2\">\n                        <button\n                            onClick={handleGenerate}\n                            disabled={isLoading}\n                            className=\"btn-primary w-full flex items-center justify-center px-6 py-3\"\n                        >\n                            {isLoading ? <LoadingSpinner /> : 'Generate Image'}\n                        </button>\n                        <button\n                            onClick={handleSurpriseMe}\n                            disabled={isLoading}\n                            className=\"px-4 py-3 bg-surface border border-border rounded-md hover:bg-gray-100 transition-colors\"\n                            title=\"Surprise Me!\"\n                        >\n                            <SparklesIcon />\n                        </button>\n                    </div>\n                </div>\n\n                {/* Right Column: Output */}\n                <div className=\"flex flex-col h-full\">\n                    <label className=\"text-sm font-medium text-text-secondary mb-2\">Generated Image</label>\n                    <div className=\"flex-grow flex items-center justify-center bg-background border-2 border-dashed border-border rounded-lg p-4 relative overflow-auto\">\n                        {isLoading && <LoadingSpinner />}\n                        {error && <p className=\"text-red-500 text-center\">{error}</p>}\n                        {generatedImageUrl && !isLoading && (\n                            <>\n                                <img src={generatedImageUrl} alt={prompt || \"Generated by AI\"} className=\"max-w-full max-h-full object-contain rounded-md shadow-lg\" />\n                                <button \n                                  onClick={handleDownload}\n                                  className=\"absolute top-4 right-4 p-2 bg-black/30 text-white rounded-full hover:bg-black/50 backdrop-blur-sm\"\n                                  title=\"Download Image\"\n                                >\n                                    <ArrowDownTrayIcon />\n                                </button>\n                            </>\n                        )}\n                        {!isLoading && !generatedImageUrl && !error && (\n                            <div className=\"text-center text-text-secondary\">\n                                <p>Your generated image will appear here.</p>\n                            </div>\n                        )}\n                    </div>\n                </div>\n            </div>\n        </div>\n    );\n};"],"names":["surprisePrompts","AiImageGenerator","prompt","setPrompt","useState","uploadedImage","setUploadedImage","generatedImageUrl","setGeneratedImageUrl","isLoading","setIsLoading","error","setError","fileInputRef","useRef","handleGenerate","useCallback","resultUrl","generateImageFromImageAndText","generateImage","err","errorMessage","handleSurpriseMe","randomPrompt","processImageBlob","blob","dataUrl","base64","blobToDataURL","fileToBase64","handlePaste","event","items","item","handleFileChange","file","handleDownload","link","jsxs","jsx","ImageGeneratorIcon","e","Fragment","XMarkIcon","LoadingSpinner","SparklesIcon","ArrowDownTrayIcon"],"mappings":"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"}