From 7f4bf7befd2a6290291b00c92d2da5666db8c076 Mon Sep 17 00:00:00 2001 From: ParagGhatage Date: Fri, 17 Jan 2025 03:16:24 +0530 Subject: [PATCH 1/4] added offline image generation with stable deffusion. --- .gitignore | 2 + backend/app/routes/images.py | 53 +- backend/main.py | 2 +- frontend/package-lock.json | 748 +++++++++++++++++- frontend/package.json | 4 +- .../components/Navigation/Sidebar/Sidebar.tsx | 82 +- frontend/src/constants/routes.ts | 3 +- .../AiImageGenration/AiImageGeneration.tsx | 226 ++++++ .../src/routes/LayoutRoutes/LayoutRoutes.tsx | 3 +- frontend/vite.config.ts | 3 +- ....timestamp-1736661610741-3f772088b0e97.mjs | 31 + 11 files changed, 1119 insertions(+), 38 deletions(-) create mode 100644 frontend/src/pages/AiImageGenration/AiImageGeneration.tsx create mode 100644 frontend/vite.config.ts.timestamp-1736661610741-3f772088b0e97.mjs diff --git a/.gitignore b/.gitignore index c32a258e..bdaa24d8 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ yarn-error.log* pnpm-debug.log* lerna-debug.log* +backend/app/models/image-generation/* + node_modules dist dist-ssr diff --git a/backend/app/routes/images.py b/backend/app/routes/images.py index 48fc9e3b..e07ecfec 100644 --- a/backend/app/routes/images.py +++ b/backend/app/routes/images.py @@ -1,9 +1,19 @@ import os import shutil import asyncio -from fastapi import APIRouter, Query -from fastapi.responses import JSONResponse +import time +import logging +from fastapi import APIRouter, Query, HTTPException +from fastapi.responses import JSONResponse, StreamingResponse +from pydantic import BaseModel +from transformers import pipeline +from diffusers import StableDiffusionPipeline, DiffusionPipeline, LCMScheduler +import torch +import matplotlib.pyplot as plt +from io import BytesIO +import base64 from PIL import Image +from fastapi import HTTPException, Query # hello from app.config.settings import IMAGES_PATH @@ -19,6 +29,7 @@ extract_metadata, ) + router = APIRouter() @@ -32,6 +43,44 @@ async def run_get_classes(img_path): detect_faces(img_path) + +print(os.curdir) + +model_path = os.path.abspath("./app/models/image-generation") +print("Model path:", model_path) +# Load the saved diffusion pipeline once +pipe = DiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float16) +pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config) +pipe.to("cuda") +print("Model loaded and ready on GPU") + +class GenerateImageRequest(BaseModel): + prompt: str +from fastapi import HTTPException, Query + +@router.post("/generate-image") +async def generate_image(prompt: str = Query(..., description="Prompt for image generation")): + try: + # Generate the image + print("request received") + image = pipe(prompt, num_inference_steps=4, guidance_scale=10.0).images[0] + + # Convert the image to a Base64 string + buffer = BytesIO() + image.save(buffer, format="PNG") + buffer.seek(0) + image_base64 = base64.b64encode(buffer.getvalue()).decode("utf-8") + # Clear GPU memory to prevent out-of-memory errors in subsequent requests + del image # Free the image object + torch.cuda.empty_cache() + # Return the JSON response with the image + return JSONResponse(content={ + "prompt": prompt, + "image": image_base64 + }) + except Exception as e: + raise HTTPException(status_code=500, detail=str(e)) + @router.get("/all-images") def get_images(): try: diff --git a/backend/main.py b/backend/main.py index f6cbd446..20f50664 100644 --- a/backend/main.py +++ b/backend/main.py @@ -39,7 +39,7 @@ async def lifespan(app: FastAPI): # Add CORS middleware app.add_middleware( CORSMiddleware, - allow_origins=["*"], # Allows all origins + allow_origins=["http://localhost:1420"], # Allows all origins allow_credentials=True, allow_methods=["*"], # Allows all methods allow_headers=["*"], # Allows all headers diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 252560ce..a63df2a6 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -9,6 +9,7 @@ "version": "0.0.0", "dependencies": { "@heroicons/react": "^2.2.0", + "@huggingface/transformers": "^3.2.4", "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-slot": "^1.1.0", @@ -22,12 +23,14 @@ "clsx": "^2.1.1", "ldrs": "^1.0.2", "lucide-react": "^0.400.0", + "onnxruntime-web": "^1.21.0-dev.20241205-d27fecd3d3", "react": "^18.2.0", "react-colorful": "^5.6.1", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.2.0", "react-icons": "^5.4.0", + "react-image-crop": "^11.0.7", "react-router-dom": "^6.24.1", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7" @@ -1932,6 +1935,16 @@ "node": ">=6.9.0" } }, + "node_modules/@emnapi/runtime": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.3.1.tgz", + "integrity": "sha512-kEBmG8KyqtxJZv+ygbEim+KCGtIq1fC22Ms3S4ziXmYKm8uyoLX0MHONVKwp+9opg390VaKRNt4a7A9NwmpNhw==", + "license": "MIT", + "optional": true, + "dependencies": { + "tslib": "^2.4.0" + } + }, "node_modules/@esbuild/aix-ppc64": { "version": "0.21.5", "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.21.5.tgz", @@ -2466,6 +2479,27 @@ "react": ">= 16 || ^19.0.0-rc" } }, + "node_modules/@huggingface/jinja": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/@huggingface/jinja/-/jinja-0.3.2.tgz", + "integrity": "sha512-F2FvuIc+w1blGsaqJI/OErRbWH6bVJDCBI8Rm5D86yZ2wlwrGERsfIaru7XUv9eYC3DMP3ixDRRtF0h6d8AZcQ==", + "license": "MIT", + "engines": { + "node": ">=18" + } + }, + "node_modules/@huggingface/transformers": { + "version": "3.2.4", + "resolved": "https://registry.npmjs.org/@huggingface/transformers/-/transformers-3.2.4.tgz", + "integrity": "sha512-XLXoC2lj72SXCftDh1ptmYwCrjDtky+WT7W51jZERU4jbKzEXz0qHC+vCZwGX+Q7nTFogdwIGU2SuaCG9XKBLA==", + "license": "Apache-2.0", + "dependencies": { + "@huggingface/jinja": "^0.3.2", + "onnxruntime-node": "1.20.1", + "onnxruntime-web": "1.21.0-dev.20241205-d27fecd3d3", + "sharp": "^0.33.5" + } + }, "node_modules/@humanwhocodes/config-array": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", @@ -2523,6 +2557,367 @@ "deprecated": "Use @eslint/object-schema instead", "dev": true }, + "node_modules/@img/sharp-darwin-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", + "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-darwin-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", + "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-darwin-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-libvips-darwin-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", + "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-darwin-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", + "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "darwin" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", + "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", + "cpu": [ + "arm" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", + "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-s390x": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", + "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", + "cpu": [ + "s390x" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linux-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-x64/-/sharp-libvips-linux-x64-1.0.4.tgz", + "integrity": "sha512-MmWmQ3iPFZr0Iev+BAgVMb3ZyC4KeFc3jFxnNbEPas60e1cIfevbtuyf9nDGIzOaW9PdnDciJm+wFFaTlj5xYw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-arm64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", + "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", + "cpu": [ + "arm64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-libvips-linuxmusl-x64": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", + "integrity": "sha512-viYN1KX9m+/hGkJtvYYp+CCLgnJXwiQB39damAO7WMdKWlIhmYTfHjwSbQeUK/20vY154mwezd9HflVFM1wVSw==", + "cpu": [ + "x64" + ], + "license": "LGPL-3.0-or-later", + "optional": true, + "os": [ + "linux" + ], + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-linux-arm": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", + "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", + "cpu": [ + "arm" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm": "1.0.5" + } + }, + "node_modules/@img/sharp-linux-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", + "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-s390x": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", + "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", + "cpu": [ + "s390x" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-s390x": "1.0.4" + } + }, + "node_modules/@img/sharp-linux-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", + "integrity": "sha512-opC+Ok5pRNAzuvq1AG0ar+1owsu842/Ab+4qvU879ippJBHvyY5n2mxF1izXqkPYlGuP/M556uh53jRLJmzTWA==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linux-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-arm64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", + "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", + "cpu": [ + "arm64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" + } + }, + "node_modules/@img/sharp-linuxmusl-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", + "integrity": "sha512-WT+d/cgqKkkKySYmqoZ8y3pxx7lx9vVejxW/W4DOFMYVSkErR+w7mf2u8m/y4+xHe7yY9DAXQMWQhpnMuFfScw==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0", + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-libvips-linuxmusl-x64": "1.0.4" + } + }, + "node_modules/@img/sharp-wasm32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", + "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", + "cpu": [ + "wasm32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later AND MIT", + "optional": true, + "dependencies": { + "@emnapi/runtime": "^1.2.0" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-ia32": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", + "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", + "cpu": [ + "ia32" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, + "node_modules/@img/sharp-win32-x64": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", + "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", + "cpu": [ + "x64" + ], + "license": "Apache-2.0 AND LGPL-3.0-or-later", + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + } + }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -2540,6 +2935,18 @@ "node": ">=12" } }, + "node_modules/@isaacs/fs-minipass": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/@isaacs/fs-minipass/-/fs-minipass-4.0.1.tgz", + "integrity": "sha512-wgm9Ehl2jpeqP3zw/7mo3kRHFp5MEDhqAdwy1fTGkHAwnkGOVsgpvQhL8B5n1qlb01jV3n/bI0ZfZp5lWA1k4w==", + "license": "ISC", + "dependencies": { + "minipass": "^7.0.4" + }, + "engines": { + "node": ">=18.0.0" + } + }, "node_modules/@jridgewell/gen-mapping": { "version": "0.3.5", "resolved": "https://registry.npmjs.org/@jridgewell/gen-mapping/-/gen-mapping-0.3.5.tgz", @@ -2664,6 +3071,70 @@ "node": ">=14" } }, + "node_modules/@protobufjs/aspromise": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/aspromise/-/aspromise-1.1.2.tgz", + "integrity": "sha512-j+gKExEuLmKwvz3OgROXtrJ2UG2x8Ch2YZUxahh+s1F2HZ+wAceUNLkvy6zKCPVRkU++ZWQrdxsUeQXmcg4uoQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/base64": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/base64/-/base64-1.1.2.tgz", + "integrity": "sha512-AZkcAA5vnN/v4PDqKyMR5lx7hZttPDgClv83E//FMNhR2TMcLUhfRUBHCmSl0oi9zMgDDqRUJkSxO3wm85+XLg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/codegen": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@protobufjs/codegen/-/codegen-2.0.4.tgz", + "integrity": "sha512-YyFaikqM5sH0ziFZCN3xDC7zeGaB/d0IUb9CATugHWbd1FRFwWwt4ld4OYMPWu5a3Xe01mGAULCdqhMlPl29Jg==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/eventemitter": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/eventemitter/-/eventemitter-1.1.0.tgz", + "integrity": "sha512-j9ednRT81vYJ9OfVuXG6ERSTdEL1xVsNgqpkxMsbIabzSo3goCjDIveeGv5d03om39ML71RdmrGNjG5SReBP/Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/fetch": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/fetch/-/fetch-1.1.0.tgz", + "integrity": "sha512-lljVXpqXebpsijW71PZaCYeIcE5on1w5DlQy5WH6GLbFryLUrBD4932W/E2BSpfRJWseIL4v/KPgBFxDOIdKpQ==", + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.1", + "@protobufjs/inquire": "^1.1.0" + } + }, + "node_modules/@protobufjs/float": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@protobufjs/float/-/float-1.0.2.tgz", + "integrity": "sha512-Ddb+kVXlXst9d+R9PfTIxh1EdNkgoRe5tOX6t01f1lYWOvJnSPDBlG241QLzcyPdoNTsblLUdujGSE4RzrTZGQ==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/inquire": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/inquire/-/inquire-1.1.0.tgz", + "integrity": "sha512-kdSefcPdruJiFMVSbn801t4vFK7KB/5gd2fYvrxhuJYg8ILrmn9SKSX2tZdV6V+ksulWqS7aXjBcRXl3wHoD9Q==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/path": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@protobufjs/path/-/path-1.1.2.tgz", + "integrity": "sha512-6JOcJ5Tm08dOHAbdR3GrvP+yUUfkjG5ePsHYczMFLq3ZmMkAD98cDgcT2iA1lJ9NVwFd4tH/iSSoe44YWkltEA==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/pool": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/pool/-/pool-1.1.0.tgz", + "integrity": "sha512-0kELaGSIDBKvcgS4zkjz1PeddatrjYcmMWOlAuAPwAeccUrPHdUqo/J6LiymHHEiJT5NrF1UVwxY14f+fy4WQw==", + "license": "BSD-3-Clause" + }, + "node_modules/@protobufjs/utf8": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@protobufjs/utf8/-/utf8-1.1.0.tgz", + "integrity": "sha512-Vvn3zZrhQZkkBE8LSuW3em98c0FwgO4nxzv6OdSxPKJIEKY2bGbHn+mhGIPerzI4twdxaP8/0+06HBpwf345Lw==", + "license": "BSD-3-Clause" + }, "node_modules/@radix-ui/primitive": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@radix-ui/primitive/-/primitive-1.1.0.tgz", @@ -3875,7 +4346,6 @@ "version": "20.16.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.16.10.tgz", "integrity": "sha512-vQUKgWTjEIRFCvK6CyriPH3MZYiYlNy0fKiEYHWbcoWLEgs4opurGGKlebrTLqdSMIbXImH6XExNiIyNUv3WpA==", - "devOptional": true, "license": "MIT", "dependencies": { "undici-types": "~6.19.2" @@ -4828,6 +5298,15 @@ "node": ">= 6" } }, + "node_modules/chownr": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/chownr/-/chownr-3.0.0.tgz", + "integrity": "sha512-+IxzY9BZOQd/XuYPRmrvEVjF/nqj5kgT4kEq7VofrDoM1MxoRjEWkrCC3EtLi59TVawxTAn+orJwFQcrqEN1+g==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/class-variance-authority": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/class-variance-authority/-/class-variance-authority-0.7.0.tgz", @@ -4858,6 +5337,19 @@ "node": ">=6" } }, + "node_modules/color": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/color/-/color-4.2.3.tgz", + "integrity": "sha512-1rXeuUUiGGrykh+CeBdu5Ie7OJwinCgQY0bc7GCRxy5xVHy+moaqkpL/jqQq0MtQOeYcrqEz4abc5f0KtU7W4A==", + "license": "MIT", + "dependencies": { + "color-convert": "^2.0.1", + "color-string": "^1.9.0" + }, + "engines": { + "node": ">=12.5.0" + } + }, "node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4874,6 +5366,16 @@ "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" }, + "node_modules/color-string": { + "version": "1.9.1", + "resolved": "https://registry.npmjs.org/color-string/-/color-string-1.9.1.tgz", + "integrity": "sha512-shrVawQFojnZv6xM40anx4CkoDP+fZsw/ZerEMsW/pyzsRbElpsL/DBVW7q3ExxwusdNXI3lXpuhEZkzs8p5Eg==", + "license": "MIT", + "dependencies": { + "color-name": "^1.0.0", + "simple-swizzle": "^0.2.2" + } + }, "node_modules/combined-stream": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz", @@ -5109,6 +5611,15 @@ "node": ">=0.4.0" } }, + "node_modules/detect-libc": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", + "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", + "license": "Apache-2.0", + "engines": { + "node": ">=8" + } + }, "node_modules/detect-node-es": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/detect-node-es/-/detect-node-es-1.1.0.tgz", @@ -6106,6 +6617,12 @@ "node": "^10.12.0 || >=12.0.0" } }, + "node_modules/flatbuffers": { + "version": "1.12.0", + "resolved": "https://registry.npmjs.org/flatbuffers/-/flatbuffers-1.12.0.tgz", + "integrity": "sha512-c7CZADjRcl6j0PlvFy0ZqXQ67qSEZfrVPynmnL+2zPc+NtMvrF8Y0QceMo7QqnSPc7+uWjUIAbvCQ5WIKlMVdQ==", + "license": "SEE LICENSE IN LICENSE.txt" + }, "node_modules/flatted": { "version": "3.3.1", "resolved": "https://registry.npmjs.org/flatted/-/flatted-3.3.1.tgz", @@ -6392,6 +6909,12 @@ "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/guid-typescript": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/guid-typescript/-/guid-typescript-1.0.9.tgz", + "integrity": "sha512-Y8T4vYhEfwJOTbouREvG+3XDsjr8E3kIr7uf+JZ0BYloFsttiHU0WfvANVsR7TxNUJa/WpCnw/Ino/p+DeBhBQ==", + "license": "ISC" + }, "node_modules/has-bigints": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", @@ -7164,6 +7687,12 @@ "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==", "dev": true }, + "node_modules/long": { + "version": "5.2.4", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.4.tgz", + "integrity": "sha512-qtzLbJE8hq7VabR3mISmVGtoXP8KGc2Z/AT8OuqlYD7JTR3oqrgwdjnk07wpj1twXxYmgDXgoKVWUG/fReSzHg==", + "license": "Apache-2.0" + }, "node_modules/loose-envify": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", @@ -7271,6 +7800,49 @@ "node": ">=16 || 14 >=14.17" } }, + "node_modules/minizlib": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/minizlib/-/minizlib-3.0.1.tgz", + "integrity": "sha512-umcy022ILvb5/3Djuu8LWeqUa8D68JaBzlttKeMWen48SjabqS3iY5w/vzeMzMUNhLDifyhbOwKDSznB1vvrwg==", + "license": "MIT", + "dependencies": { + "minipass": "^7.0.4", + "rimraf": "^5.0.5" + }, + "engines": { + "node": ">= 18" + } + }, + "node_modules/minizlib/node_modules/rimraf": { + "version": "5.0.10", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-5.0.10.tgz", + "integrity": "sha512-l0OE8wL34P4nJH/H2ffoaniAokM2qSmrtXHmlpvYr5AVVX8msAyW0l8NVJFDxlSK4u3Uh/f41cQheDVdnYijwQ==", + "license": "ISC", + "dependencies": { + "glob": "^10.3.7" + }, + "bin": { + "rimraf": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/mkdirp": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-3.0.1.tgz", + "integrity": "sha512-+NsyUUAZDmo6YVHzL/stxSu3t9YS1iljliy3BSDrXJ/dkn1KYdmtZODGGjLcc9XLgVVpH4KshHB8XmZgMhaBXg==", + "license": "MIT", + "bin": { + "mkdirp": "dist/cjs/src/bin.js" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/ms": { "version": "2.1.3", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", @@ -7474,6 +8046,48 @@ "wrappy": "1" } }, + "node_modules/onnxruntime-common": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.20.1.tgz", + "integrity": "sha512-YiU0s0IzYYC+gWvqD1HzLc46Du1sXpSiwzKb63PACIJr6LfL27VsXSXQvt68EzD3V0D5Bc0vyJTjmMxp0ylQiw==", + "license": "MIT" + }, + "node_modules/onnxruntime-node": { + "version": "1.20.1", + "resolved": "https://registry.npmjs.org/onnxruntime-node/-/onnxruntime-node-1.20.1.tgz", + "integrity": "sha512-di/I4HDXRw+FLgq+TyHmQEDd3cEp9iFFZm0r4uJ1Wd7b/WE1VXtKWo8yemex347c6GNF/3Pv86ZfPhIWxORr0w==", + "hasInstallScript": true, + "license": "MIT", + "os": [ + "win32", + "darwin", + "linux" + ], + "dependencies": { + "onnxruntime-common": "1.20.1", + "tar": "^7.0.1" + } + }, + "node_modules/onnxruntime-web": { + "version": "1.21.0-dev.20241205-d27fecd3d3", + "resolved": "https://registry.npmjs.org/onnxruntime-web/-/onnxruntime-web-1.21.0-dev.20241205-d27fecd3d3.tgz", + "integrity": "sha512-neeC9mv1sFWjUFrTaDl7enufNxbtSSTwR5V2i35ga4yXWS6r1MbpUwWwD1X+VKANujbSG8M5pk/ohRAOm2QhMQ==", + "license": "MIT", + "dependencies": { + "flatbuffers": "^1.12.0", + "guid-typescript": "^1.0.9", + "long": "^5.2.3", + "onnxruntime-common": "1.21.0-dev.20241205-6ed77cc374", + "platform": "^1.3.6", + "protobufjs": "^7.2.4" + } + }, + "node_modules/onnxruntime-web/node_modules/onnxruntime-common": { + "version": "1.21.0-dev.20241205-6ed77cc374", + "resolved": "https://registry.npmjs.org/onnxruntime-common/-/onnxruntime-common-1.21.0-dev.20241205-6ed77cc374.tgz", + "integrity": "sha512-U4DGq/dZiboIEK0Zv1KUuWJesJ/txUALpWSXwI8kqOCSxe8GrI65xfRFeMbqYFhPVGAWZPsBpT1zo1s4ksrlrg==", + "license": "MIT" + }, "node_modules/optionator": { "version": "0.9.4", "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.9.4.tgz", @@ -7657,6 +8271,12 @@ "node": ">= 6" } }, + "node_modules/platform": { + "version": "1.3.6", + "resolved": "https://registry.npmjs.org/platform/-/platform-1.3.6.tgz", + "integrity": "sha512-fnWVljUchTro6RiCFvCXBbNhJc2NijN7oIQxbwsyL0buWJPG85v81ehlHI9fXrJsMNgTofEoWIQeClKpgxFLrg==", + "license": "MIT" + }, "node_modules/possible-typed-array-names": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/possible-typed-array-names/-/possible-typed-array-names-1.0.0.tgz", @@ -7922,6 +8542,30 @@ "react-is": "^16.13.1" } }, + "node_modules/protobufjs": { + "version": "7.4.0", + "resolved": "https://registry.npmjs.org/protobufjs/-/protobufjs-7.4.0.tgz", + "integrity": "sha512-mRUWCc3KUU4w1jU8sGxICXH/gNS94DvI1gxqDvBzhj1JpcsimQkYiOJfwsPUykUI5ZaspFbSgmBLER8IrQ3tqw==", + "hasInstallScript": true, + "license": "BSD-3-Clause", + "dependencies": { + "@protobufjs/aspromise": "^1.1.2", + "@protobufjs/base64": "^1.1.2", + "@protobufjs/codegen": "^2.0.4", + "@protobufjs/eventemitter": "^1.1.0", + "@protobufjs/fetch": "^1.1.0", + "@protobufjs/float": "^1.0.2", + "@protobufjs/inquire": "^1.1.0", + "@protobufjs/path": "^1.1.2", + "@protobufjs/pool": "^1.1.0", + "@protobufjs/utf8": "^1.1.0", + "@types/node": ">=13.7.0", + "long": "^5.0.0" + }, + "engines": { + "node": ">=12.0.0" + } + }, "node_modules/proxy-from-env": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", @@ -8040,6 +8684,15 @@ "react": "*" } }, + "node_modules/react-image-crop": { + "version": "11.0.7", + "resolved": "https://registry.npmjs.org/react-image-crop/-/react-image-crop-11.0.7.tgz", + "integrity": "sha512-ZciKWHDYzmm366JDL18CbrVyjnjH0ojufGDmScfS4ZUqLHg4nm6ATY+K62C75W4ZRNt4Ii+tX0bSjNk9LQ2xzQ==", + "license": "ISC", + "peerDependencies": { + "react": ">=16.13.1" + } + }, "node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", @@ -8533,6 +9186,57 @@ "node": ">= 0.4" } }, + "node_modules/sharp": { + "version": "0.33.5", + "resolved": "https://registry.npmjs.org/sharp/-/sharp-0.33.5.tgz", + "integrity": "sha512-haPVm1EkS9pgvHrQ/F3Xy+hgcuMV0Wm9vfIBSiwZ05k+xgb0PkBQpGsAA/oWdDobNaZTH5ppvHtzCFbnSEwHVw==", + "hasInstallScript": true, + "license": "Apache-2.0", + "dependencies": { + "color": "^4.2.3", + "detect-libc": "^2.0.3", + "semver": "^7.6.3" + }, + "engines": { + "node": "^18.17.0 || ^20.3.0 || >=21.0.0" + }, + "funding": { + "url": "https://opencollective.com/libvips" + }, + "optionalDependencies": { + "@img/sharp-darwin-arm64": "0.33.5", + "@img/sharp-darwin-x64": "0.33.5", + "@img/sharp-libvips-darwin-arm64": "1.0.4", + "@img/sharp-libvips-darwin-x64": "1.0.4", + "@img/sharp-libvips-linux-arm": "1.0.5", + "@img/sharp-libvips-linux-arm64": "1.0.4", + "@img/sharp-libvips-linux-s390x": "1.0.4", + "@img/sharp-libvips-linux-x64": "1.0.4", + "@img/sharp-libvips-linuxmusl-arm64": "1.0.4", + "@img/sharp-libvips-linuxmusl-x64": "1.0.4", + "@img/sharp-linux-arm": "0.33.5", + "@img/sharp-linux-arm64": "0.33.5", + "@img/sharp-linux-s390x": "0.33.5", + "@img/sharp-linux-x64": "0.33.5", + "@img/sharp-linuxmusl-arm64": "0.33.5", + "@img/sharp-linuxmusl-x64": "0.33.5", + "@img/sharp-wasm32": "0.33.5", + "@img/sharp-win32-ia32": "0.33.5", + "@img/sharp-win32-x64": "0.33.5" + } + }, + "node_modules/sharp/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "license": "ISC", + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -8584,6 +9288,21 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/simple-swizzle": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/simple-swizzle/-/simple-swizzle-0.2.2.tgz", + "integrity": "sha512-JA//kQgZtbuY83m+xT+tXJkmJncGMTFT+C+g2h2R9uxkYIrE2yy9sgmcLhCnw57/WSD+Eh3J97FPEDFnbXnDUg==", + "license": "MIT", + "dependencies": { + "is-arrayish": "^0.3.1" + } + }, + "node_modules/simple-swizzle/node_modules/is-arrayish": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.3.2.tgz", + "integrity": "sha512-eVRqCvVlZbuw3GrM63ovNSNAeA1K16kaR/LRY/92w0zxQ5/1YzwblUX652i4Xs9RwAGjW9d9y6X88t8OaAJfWQ==", + "license": "MIT" + }, "node_modules/slash": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz", @@ -8926,6 +9645,32 @@ "tailwindcss": ">=3.0.0 || insiders" } }, + "node_modules/tar": { + "version": "7.4.3", + "resolved": "https://registry.npmjs.org/tar/-/tar-7.4.3.tgz", + "integrity": "sha512-5S7Va8hKfV7W5U6g3aYxXmlPoZVAwUMy9AOKyF2fVuZa2UD3qZjg578OrLRt8PcNN1PleVaL/5/yYATNL0ICUw==", + "license": "ISC", + "dependencies": { + "@isaacs/fs-minipass": "^4.0.0", + "chownr": "^3.0.0", + "minipass": "^7.1.2", + "minizlib": "^3.0.1", + "mkdirp": "^3.0.1", + "yallist": "^5.0.0" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/tar/node_modules/yallist": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-5.0.0.tgz", + "integrity": "sha512-YgvUTfwqyc7UXVMrB+SImsVYSmTS8X/tSrtdNZMImM+n7+QTriRXyXim0mBrTXNeqzVF0KWGgHPeiyViFFrNDw==", + "license": "BlueOak-1.0.0", + "engines": { + "node": ">=18" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -9151,7 +9896,6 @@ "version": "6.19.8", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==", - "devOptional": true, "license": "MIT" }, "node_modules/unicode-canonical-property-names-ecmascript": { diff --git a/frontend/package.json b/frontend/package.json index a0c049ed..a258a499 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -16,6 +16,7 @@ }, "dependencies": { "@heroicons/react": "^2.2.0", + "@huggingface/transformers": "^3.2.4", "@radix-ui/react-dialog": "^1.1.1", "@radix-ui/react-dropdown-menu": "^2.1.1", "@radix-ui/react-slot": "^1.1.0", @@ -29,13 +30,14 @@ "clsx": "^2.1.1", "ldrs": "^1.0.2", "lucide-react": "^0.400.0", + "onnxruntime-web": "^1.21.0-dev.20241205-d27fecd3d3", "react": "^18.2.0", "react-colorful": "^5.6.1", "react-dnd": "^16.0.1", "react-dnd-html5-backend": "^16.0.1", "react-dom": "^18.2.0", - "react-image-crop": "^11.0.7", "react-icons": "^5.4.0", + "react-image-crop": "^11.0.7", "react-router-dom": "^6.24.1", "tailwind-merge": "^2.3.0", "tailwindcss-animate": "^1.0.7" diff --git a/frontend/src/components/Navigation/Sidebar/Sidebar.tsx b/frontend/src/components/Navigation/Sidebar/Sidebar.tsx index d01ae0d7..ebf89b8d 100644 --- a/frontend/src/components/Navigation/Sidebar/Sidebar.tsx +++ b/frontend/src/components/Navigation/Sidebar/Sidebar.tsx @@ -1,44 +1,68 @@ -import { Link, useLocation } from 'react-router-dom'; -import { Home, Sparkles, Video, Images, Settings } from 'lucide-react'; -import { useState } from 'react'; +import React, { useState } from 'react' +import { Link, useLocation } from 'react-router-dom' +import { Home, Sparkles, Video, Images, Settings, Wand2 } from 'lucide-react' -const Sidebar = () => { - const location = useLocation(); - const [isExpanded, setIsExpanded] = useState(false); +interface NavItem { + path: string + label: string + Icon: React.ElementType +} - const isActive = (path: string) => location.pathname === path; +const Sidebar: React.FC = () => { + const location = useLocation() + const [isExpanded, setIsExpanded] = useState(false) - const handleMouseEnter = () => setIsExpanded(true); - const handleMouseLeave = () => setIsExpanded(false); + const isActive = (path: string): boolean => location.pathname === path - const linkClasses = (path: string) => { + const handleMouseEnter = (): void => setIsExpanded(true) + const handleMouseLeave = (): void => setIsExpanded(false) + + const linkClasses = (path: string): string => { const baseClasses = - 'group flex flex-col items-center gap-2 p-3 rounded-xl transition-all duration-200'; - const activeClasses = isActive(path) - ? 'bg-gray-200 text-gray-900 dark:bg-gray-700 dark:text-gray-100' - : 'text-gray-500 dark:text-gray-300'; - return `${baseClasses} ${activeClasses}`; - }; + 'group flex flex-col items-center gap-2 p-3 rounded-xl transition-all duration-200' + + const activeClasses = ` + bg-white/95 dark:bg-white/10 + text-gray-900 dark:text-gray-100 + shadow-md dark:shadow-gray-900/30 + backdrop-blur-md backdrop-saturate-150 + border border-gray-200 dark:border-gray-700 + ` + + const inactiveClasses = ` + bg-transparent hover:bg-gray-50 dark:hover:bg-white/10 + text-gray-700 dark:text-gray-400 + hover:text-gray-900 dark:hover:text-gray-100 + border border-transparent + hover:border-gray-200 dark:hover:border-gray-700 + hover:shadow-sm dark:hover:shadow-gray-900/20 + ` + + return `${baseClasses} ${isActive(path) ? activeClasses : inactiveClasses}` + } const iconClasses = - 'h-5 w-5 transition-transform duration-200 ease-out group-hover:scale-110'; + 'h-5 w-5 transition-transform duration-200 ease-out group-hover:scale-110' + + const navItems: NavItem[] = [ + { path: '/home', label: 'Home', Icon: Home }, + { path: '/ai-tagging', label: 'AI Tagging', Icon: Sparkles }, + { path: '/videos', label: 'Videos', Icon: Video }, + { path: '/albums', label: 'Albums', Icon: Images }, + { path: '/image-generation', label: 'Generate Image', Icon: Wand2 }, + { path: '/settings', label: 'Settings', Icon: Settings }, + ] return (
- {[ - { path: '/home', label: 'Home', Icon: Home }, - { path: '/ai-tagging', label: 'AI Tagging', Icon: Sparkles }, - { path: '/videos', label: 'Videos', Icon: Video }, - { path: '/albums', label: 'Albums', Icon: Images }, - { path: '/settings', label: 'Settings', Icon: Settings }, - ].map(({ path, label, Icon }) => ( + {navItems.map(({ path, label, Icon }) => ( { > @@ -63,7 +87,7 @@ const Sidebar = () => { ))}
- ); -}; + ) +} -export default Sidebar; +export default Sidebar diff --git a/frontend/src/constants/routes.ts b/frontend/src/constants/routes.ts index a076f573..f926ee98 100644 --- a/frontend/src/constants/routes.ts +++ b/frontend/src/constants/routes.ts @@ -8,5 +8,6 @@ export const ROUTES = { VIDEOS: '/videos', SETTINGS: '/settings', ALBUM: '/albums', + AIIMAGEGENRATION: '/image-generation' }, -}; +}; \ No newline at end of file diff --git a/frontend/src/pages/AiImageGenration/AiImageGeneration.tsx b/frontend/src/pages/AiImageGenration/AiImageGeneration.tsx new file mode 100644 index 00000000..bf3886b5 --- /dev/null +++ b/frontend/src/pages/AiImageGenration/AiImageGeneration.tsx @@ -0,0 +1,226 @@ +import React, { useState } from 'react'; +import { Download, Link, Sparkles, Heart, Eraser, Wand2 } from 'lucide-react'; + +const AiImageGeneration = () => { + const [prompt, setPrompt] = useState(''); + const [isGenerating, setIsGenerating] = useState(false); + const [generatedImage, setGeneratedImage] = useState(null); + const [error, setError] = useState(null); + const [showCopied, setShowCopied] = useState(false); + + const [magicWords] = useState(['mystical', 'ethereal', 'vibrant', 'dreamy', 'cosmic']); + const [selectedStyle, setSelectedStyle] = useState(''); + const [showTooltip, setShowTooltip] = useState(''); + const [imageScale, setImageScale] = useState(1); + + const artStyles = [ + { name: '🎨 Artistic', key: 'artistic' }, + { name: '📷 Realistic', key: 'realistic' }, + { name: '✨ Fantasy', key: 'fantasy' }, + { name: '🌌 Cosmic', key: 'cosmic' }, + ]; + + const handleSubmit = async (e) => { + e.preventDefault(); + if (!prompt) return; + + setIsGenerating(true); + setError(null); + + try { + const response = await fetch(`http://localhost:8000/images/generate-image?prompt=${encodeURIComponent(prompt)}`, { + method: 'POST', + }); + + console.log(response) + if (!response.ok) { + throw new Error('Failed to generate image.'); + } + + const data = await response.json(); + if (data.image) { + setGeneratedImage(`data:image/png;base64,${data.image}`); + } else { + setError('Image generation failed. No image data received.'); + } + } catch (err) { + setError('Failed to generate image. Please try again.'); + } finally { + setIsGenerating(false); + } + }; + + const handleMagicWord = (word) => { + setPrompt((prev) => `${prev} ${word}`.trim()); + }; + + const handleStyleSelect = (style) => { + setSelectedStyle(style); + setPrompt((prev) => `${prev} in ${style} style`.trim()); + }; + + return ( +
+
+ {/* Interactive Header */} +
+

setShowTooltip('Create something magical!')} + onMouseLeave={() => setShowTooltip('')} + > + PictoPy + +

+ {showTooltip && ( +
+ {showTooltip} +
+ )} +

+ Where imagination meets artificial intelligence - Create stunning visuals with our + advanced AI image generator. +

+
+ + {/* Magic Words Bar */} +
+ {magicWords.map((word) => ( + + ))} +
+ + {/* Style Selection */} +
+ {artStyles.map((style) => ( + + ))} +
+ + {/* Input Form */} +
+
+
+ + setPrompt(e.target.value)} + placeholder="Describe your imagination..." + className="w-full pl-12 pr-24 py-3 text-gray-700 bg-white border border-gray-200 rounded-lg focus:outline-none focus:border-purple-500 transition-all hover:border-purple-300 dark:bg-gray-700 dark:text-white dark:border-gray-600 dark:focus:border-purple-400" + /> + {prompt && ( + + )} +
+ +
+
+ + {/* Generated Image Display */} + {generatedImage && ( +
+
+ AI generated setImageScale(1.02)} + onMouseLeave={() => setImageScale(1)} + /> +
+ + +
+
+
+ )} + + {error && ( +
+ {error} +
+ )} +
+ +
+ ); +}; + +export default AiImageGeneration; diff --git a/frontend/src/routes/LayoutRoutes/LayoutRoutes.tsx b/frontend/src/routes/LayoutRoutes/LayoutRoutes.tsx index 6134a36f..91c5b032 100644 --- a/frontend/src/routes/LayoutRoutes/LayoutRoutes.tsx +++ b/frontend/src/routes/LayoutRoutes/LayoutRoutes.tsx @@ -4,7 +4,7 @@ import Album from '@/pages/Album/Album'; import Dashboard from '@/pages/Dashboard/Dashboard'; import Settings from '@/pages/SettingsPage/Settings'; import Videos from '@/pages/VideosPage/Videos'; - +import AiImageGeneration from '@/pages/AiImageGenration/AiImageGeneration'; import React from 'react'; import { Routes, Route } from 'react-router-dom'; @@ -15,5 +15,6 @@ export const LayoutRoutes: React.FC = () => ( } /> } /> } /> + }/> ); diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts index 907a2059..554dc29a 100644 --- a/frontend/vite.config.ts +++ b/frontend/vite.config.ts @@ -19,10 +19,11 @@ export default defineConfig(async () => ({ // 2. tauri expects a fixed port, fail if that port is not available server: { port: 1420, - strictPort: true, + strictPort: false, watch: { // 3. tell vite to ignore watching `src-tauri` ignored: ['**/src-tauri/**'], }, + }, })); diff --git a/frontend/vite.config.ts.timestamp-1736661610741-3f772088b0e97.mjs b/frontend/vite.config.ts.timestamp-1736661610741-3f772088b0e97.mjs new file mode 100644 index 00000000..44c974e9 --- /dev/null +++ b/frontend/vite.config.ts.timestamp-1736661610741-3f772088b0e97.mjs @@ -0,0 +1,31 @@ +// vite.config.ts +import { defineConfig } from "file:///A:/PROFESSIONAL/PROGRAMMING/GSOC/AOSSIE/Parag-PictoPy/frontend/node_modules/vite/dist/node/index.js"; +import react from "file:///A:/PROFESSIONAL/PROGRAMMING/GSOC/AOSSIE/Parag-PictoPy/frontend/node_modules/@vitejs/plugin-react/dist/index.mjs"; +import path from "path"; +import eslint from "file:///A:/PROFESSIONAL/PROGRAMMING/GSOC/AOSSIE/Parag-PictoPy/frontend/node_modules/vite-plugin-eslint/dist/index.mjs"; +var __vite_injected_original_dirname = "A:\\PROFESSIONAL\\PROGRAMMING\\GSOC\\AOSSIE\\Parag-PictoPy\\frontend"; +var vite_config_default = defineConfig(async () => ({ + plugins: [react(), eslint()], + resolve: { + alias: { + "@": path.resolve(__vite_injected_original_dirname, "./src") + } + }, + // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` + // + // 1. prevent vite from obscuring rust errors + clearScreen: false, + // 2. tauri expects a fixed port, fail if that port is not available + server: { + port: 1420, + strictPort: true, + watch: { + // 3. tell vite to ignore watching `src-tauri` + ignored: ["**/src-tauri/**"] + } + } +})); +export { + vite_config_default as default +}; +//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsidml0ZS5jb25maWcudHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbImNvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9kaXJuYW1lID0gXCJBOlxcXFxQUk9GRVNTSU9OQUxcXFxcUFJPR1JBTU1JTkdcXFxcR1NPQ1xcXFxBT1NTSUVcXFxcUGFyYWctUGljdG9QeVxcXFxmcm9udGVuZFwiO2NvbnN0IF9fdml0ZV9pbmplY3RlZF9vcmlnaW5hbF9maWxlbmFtZSA9IFwiQTpcXFxcUFJPRkVTU0lPTkFMXFxcXFBST0dSQU1NSU5HXFxcXEdTT0NcXFxcQU9TU0lFXFxcXFBhcmFnLVBpY3RvUHlcXFxcZnJvbnRlbmRcXFxcdml0ZS5jb25maWcudHNcIjtjb25zdCBfX3ZpdGVfaW5qZWN0ZWRfb3JpZ2luYWxfaW1wb3J0X21ldGFfdXJsID0gXCJmaWxlOi8vL0E6L1BST0ZFU1NJT05BTC9QUk9HUkFNTUlORy9HU09DL0FPU1NJRS9QYXJhZy1QaWN0b1B5L2Zyb250ZW5kL3ZpdGUuY29uZmlnLnRzXCI7aW1wb3J0IHsgZGVmaW5lQ29uZmlnIH0gZnJvbSAndml0ZSc7XHJcbmltcG9ydCByZWFjdCBmcm9tICdAdml0ZWpzL3BsdWdpbi1yZWFjdCc7XHJcbmltcG9ydCBwYXRoIGZyb20gJ3BhdGgnO1xyXG5pbXBvcnQgZXNsaW50IGZyb20gJ3ZpdGUtcGx1Z2luLWVzbGludCc7XHJcblxyXG4vLyBodHRwczovL3ZpdGVqcy5kZXYvY29uZmlnL1xyXG5leHBvcnQgZGVmYXVsdCBkZWZpbmVDb25maWcoYXN5bmMgKCkgPT4gKHtcclxuICBwbHVnaW5zOiBbcmVhY3QoKSwgZXNsaW50KCldLFxyXG5cclxuICByZXNvbHZlOiB7XHJcbiAgICBhbGlhczoge1xyXG4gICAgICAnQCc6IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuL3NyYycpLFxyXG4gICAgfSxcclxuICB9LFxyXG4gIC8vIFZpdGUgb3B0aW9ucyB0YWlsb3JlZCBmb3IgVGF1cmkgZGV2ZWxvcG1lbnQgYW5kIG9ubHkgYXBwbGllZCBpbiBgdGF1cmkgZGV2YCBvciBgdGF1cmkgYnVpbGRgXHJcbiAgLy9cclxuICAvLyAxLiBwcmV2ZW50IHZpdGUgZnJvbSBvYnNjdXJpbmcgcnVzdCBlcnJvcnNcclxuICBjbGVhclNjcmVlbjogZmFsc2UsXHJcbiAgLy8gMi4gdGF1cmkgZXhwZWN0cyBhIGZpeGVkIHBvcnQsIGZhaWwgaWYgdGhhdCBwb3J0IGlzIG5vdCBhdmFpbGFibGVcclxuICBzZXJ2ZXI6IHtcclxuICAgIHBvcnQ6IDE0MjAsXHJcbiAgICBzdHJpY3RQb3J0OiB0cnVlLFxyXG4gICAgd2F0Y2g6IHtcclxuICAgICAgLy8gMy4gdGVsbCB2aXRlIHRvIGlnbm9yZSB3YXRjaGluZyBgc3JjLXRhdXJpYFxyXG4gICAgICBpZ25vcmVkOiBbJyoqL3NyYy10YXVyaS8qKiddLFxyXG4gICAgfSxcclxuICB9LFxyXG59KSk7XHJcbiJdLAogICJtYXBwaW5ncyI6ICI7QUFBMFgsU0FBUyxvQkFBb0I7QUFDdlosT0FBTyxXQUFXO0FBQ2xCLE9BQU8sVUFBVTtBQUNqQixPQUFPLFlBQVk7QUFIbkIsSUFBTSxtQ0FBbUM7QUFNekMsSUFBTyxzQkFBUSxhQUFhLGFBQWE7QUFBQSxFQUN2QyxTQUFTLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQztBQUFBLEVBRTNCLFNBQVM7QUFBQSxJQUNQLE9BQU87QUFBQSxNQUNMLEtBQUssS0FBSyxRQUFRLGtDQUFXLE9BQU87QUFBQSxJQUN0QztBQUFBLEVBQ0Y7QUFBQTtBQUFBO0FBQUE7QUFBQSxFQUlBLGFBQWE7QUFBQTtBQUFBLEVBRWIsUUFBUTtBQUFBLElBQ04sTUFBTTtBQUFBLElBQ04sWUFBWTtBQUFBLElBQ1osT0FBTztBQUFBO0FBQUEsTUFFTCxTQUFTLENBQUMsaUJBQWlCO0FBQUEsSUFDN0I7QUFBQSxFQUNGO0FBQ0YsRUFBRTsiLAogICJuYW1lcyI6IFtdCn0K From 88c3c3caf7ebfa26b22a5107222c0e37695696cb Mon Sep 17 00:00:00 2001 From: ParagGhatage Date: Sat, 25 Jan 2025 23:21:50 +0530 Subject: [PATCH 2/4] Decresed image generation model size from 4GB to 2.5 GB, optimized backend script for image generation. --- backend/app/routes/images.py | 76 ++++++++++++++----- .../AiImageGenration/AiImageGeneration.tsx | 11 +-- 2 files changed, 59 insertions(+), 28 deletions(-) diff --git a/backend/app/routes/images.py b/backend/app/routes/images.py index e07ecfec..da475522 100644 --- a/backend/app/routes/images.py +++ b/backend/app/routes/images.py @@ -29,6 +29,22 @@ extract_metadata, ) +from diffusers import StableDiffusionPipeline, LCMScheduler +from transformers import BitsAndBytesConfig +import torch +from fastapi import FastAPI, HTTPException, Query +from pydantic import BaseModel +from fastapi.responses import JSONResponse +from io import BytesIO +import base64 +import os +import asyncio +from diffusers import StableDiffusionPipeline +import torch +import warnings +import numpy as np +import warnings + router = APIRouter() @@ -47,39 +63,59 @@ async def run_get_classes(img_path): print(os.curdir) model_path = os.path.abspath("./app/models/image-generation") -print("Model path:", model_path) -# Load the saved diffusion pipeline once -pipe = DiffusionPipeline.from_pretrained(model_path, torch_dtype=torch.float16) -pipe.scheduler = LCMScheduler.from_config(pipe.scheduler.config) -pipe.to("cuda") -print("Model loaded and ready on GPU") - -class GenerateImageRequest(BaseModel): - prompt: str -from fastapi import HTTPException, Query +# Check if GPU is available +device = "cuda" if torch.cuda.is_available() else "cpu" +print(f"Using device: {device}") + + +# Load the Stable Diffusion pipeline +pipe = StableDiffusionPipeline.from_pretrained( + model_path, + torch_dtype=torch.float32, +) + +if(device=="cuda"): + pipe.to("cuda") +else: + pipe.to("cpu") + +pipe.enable_attention_slicing() + + +# Route to generate an image @router.post("/generate-image") async def generate_image(prompt: str = Query(..., description="Prompt for image generation")): + """ + Generate an image using the Stable Diffusion model. + Example: http://localhost:8000/generate-image?prompt=Astronaut%20in%20a%20jungle + """ try: - # Generate the image - print("request received") - image = pipe(prompt, num_inference_steps=4, guidance_scale=10.0).images[0] + print("Request received with prompt:", prompt) - # Convert the image to a Base64 string + + image = pipe(prompt, num_inference_steps=5).images[0] + buffer = BytesIO() - image.save(buffer, format="PNG") + image.save(buffer, format="PNG") buffer.seek(0) + + # Convert image to Base64 image_base64 = base64.b64encode(buffer.getvalue()).decode("utf-8") - # Clear GPU memory to prevent out-of-memory errors in subsequent requests - del image # Free the image object - torch.cuda.empty_cache() - # Return the JSON response with the image + + del image + + if device == "cuda": + torch.cuda.empty_cache() + # Return JSON response return JSONResponse(content={ "prompt": prompt, "image": image_base64 }) except Exception as e: - raise HTTPException(status_code=500, detail=str(e)) + print(f"Error generating image: {e}") + raise HTTPException(status_code=500, detail=f"Image generation failed: {str(e)}") + @router.get("/all-images") def get_images(): diff --git a/frontend/src/pages/AiImageGenration/AiImageGeneration.tsx b/frontend/src/pages/AiImageGenration/AiImageGeneration.tsx index bf3886b5..d3ce38a8 100644 --- a/frontend/src/pages/AiImageGenration/AiImageGeneration.tsx +++ b/frontend/src/pages/AiImageGenration/AiImageGeneration.tsx @@ -209,14 +209,9 @@ const AiImageGeneration = () => { From 9a59411d25ed5b372849b3b6985107d8b95b4127 Mon Sep 17 00:00:00 2001 From: Parag Ghatage Date: Sun, 26 Jan 2025 01:08:11 +0530 Subject: [PATCH 3/4] Delete backend/main.py --- backend/main.py | 57 ------------------------------------------------- 1 file changed, 57 deletions(-) delete mode 100644 backend/main.py diff --git a/backend/main.py b/backend/main.py deleted file mode 100644 index 20f50664..00000000 --- a/backend/main.py +++ /dev/null @@ -1,57 +0,0 @@ -""" -This module contains the main FastAPI application. -""" - -from time import sleep -from fastapi import FastAPI -from fastapi.middleware.cors import CORSMiddleware - -from contextlib import asynccontextmanager - -from app.database.faces import cleanup_face_embeddings, create_faces_table -from app.database.images import create_image_id_mapping_table, create_images_table -from app.database.albums import create_albums_table -from app.database.yolo_mapping import create_YOLO_mappings -from app.facecluster.init_face_cluster import get_face_cluster, init_face_cluster -from app.routes.test import router as test_router -from app.routes.images import router as images_router -from app.routes.albums import router as albums_router -from app.routes.facetagging import router as tagging_router - - -@asynccontextmanager -async def lifespan(app: FastAPI): - create_YOLO_mappings() - create_faces_table() - create_image_id_mapping_table() - create_images_table() - create_albums_table() - cleanup_face_embeddings() - init_face_cluster() - yield - face_cluster = get_face_cluster() - if face_cluster: - face_cluster.save_to_db() - - -app = FastAPI(lifespan=lifespan) - -# Add CORS middleware -app.add_middleware( - CORSMiddleware, - allow_origins=["http://localhost:1420"], # Allows all origins - allow_credentials=True, - allow_methods=["*"], # Allows all methods - allow_headers=["*"], # Allows all headers -) - - -@app.get("/") -async def root(): - return {"message": "PictoPy Server is up and running!"} - - -app.include_router(test_router, prefix="/test", tags=["Test"]) -app.include_router(images_router, prefix="/images", tags=["Images"]) -app.include_router(albums_router, prefix="/albums", tags=["Albums"]) -app.include_router(tagging_router, prefix="/tag", tags=["Tagging"]) From 4da55441ff914d79c2a1bb2fb90941afa35fc57c Mon Sep 17 00:00:00 2001 From: Parag Ghatage Date: Sun, 26 Jan 2025 01:10:38 +0530 Subject: [PATCH 4/4] Delete frontend/vite.config.ts --- frontend/vite.config.ts | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 frontend/vite.config.ts diff --git a/frontend/vite.config.ts b/frontend/vite.config.ts deleted file mode 100644 index 554dc29a..00000000 --- a/frontend/vite.config.ts +++ /dev/null @@ -1,29 +0,0 @@ -import { defineConfig } from 'vite'; -import react from '@vitejs/plugin-react'; -import path from 'path'; -import eslint from 'vite-plugin-eslint'; - -// https://vitejs.dev/config/ -export default defineConfig(async () => ({ - plugins: [react(), eslint()], - - resolve: { - alias: { - '@': path.resolve(__dirname, './src'), - }, - }, - // Vite options tailored for Tauri development and only applied in `tauri dev` or `tauri build` - // - // 1. prevent vite from obscuring rust errors - clearScreen: false, - // 2. tauri expects a fixed port, fail if that port is not available - server: { - port: 1420, - strictPort: false, - watch: { - // 3. tell vite to ignore watching `src-tauri` - ignored: ['**/src-tauri/**'], - }, - - }, -}));