Visual Echoใฏใ็ๆAIใๆดป็จใใ้ๅๆใปๅๅฒๅใฎ็ปๅ้ฃๆณใฒใผใ ใงใใ
็ปๅใ่จ่ใง่กจ็พใใAIใใใฎ่จ่ใใๆฐใใ็ปๅใ็ๆใใใฎ้ฃ้ใซใใฃใฆใๅฝๅใฎๆๅณใใ้ขใใฆใใ๏ผใใใใฏๅฅ่ทก็ใซ็ถญๆใใใ๏ผ่ฆ่ฆ็ใชๅค้ทใๆฅฝใใใใจใใงใใพใใ
- ๐ณ ใใชใผๆง้ : Gitใฎใใฉใณใใฎใใใซใ1ใคใฎ็ปๅใใ่คๆฐใฎ่งฃ้ใๅๅฒ
- ๐ ้ๅๆๅฆ็: ใชใขใซใฟใคใ ๆงใๅฟ ่ฆใจใใใ่ชๅใฎใใผในใงใใฌใคๅฏ่ฝ
- ๐ฏ ่ฆ่ฆๅ: ใคใณใฟใฉใฏใใฃใใชใใชใผใใฅใผใงๅ จไฝใฎ้ฃ้ใไฟฏ็ฐ
- ๐จ AI็ๆ: Google Gemini 2.5 Flash Imageใซใใ้ซๅ่ณชใช็ปๅ็ๆ
- ๐ ็ณป่ญ่ฟฝ่ทก: ็ปๅใฎ่ช็ใใ็พๅจใพใงใใในใฆใฎๅค้ทใ่ฟฝ่ทกๅฏ่ฝ
ใฉใณใใ ใซ้ธใฐใใ3ๆใฎ็ปๅใ่กจ็คบใๅ็ปๅใใๆฐใใ้ฃ้ใ้ๅงใงใใพใใ
ใในใฆใฎ็ปๅใฎ้ฃ้ใๆจๆง้ ใงๅฏ่ฆๅใใบใผใ ใปใใณๆไฝใซๅฏพๅฟใ
็ปๅใฎ็ณป่ญ๏ผใซใผใใใ็พๅจใพใง๏ผใ่ฆ่ฆ็ใซ่กจ็คบใใๆฐใใ่งฃ้ใ่ฟฝๅ ใงใใพใใ
| ใซใใดใช | ๆ่ก | ็จ้ |
|---|---|---|
| Frontend | Next.js 15 (App Router) | React 19ใใผในใฎใใซในใฟใใฏใใฌใผใ ใฏใผใฏ |
| Language | TypeScript 5 | ๅๅฎๅ จใช้็บ็ฐๅข |
| Database | Supabase (PostgreSQL) | ใชใขใซใฟใคใ ใใผใฟใใผใน |
| AI Model | Google Gemini 2.5 Flash Image | Text-to-Image็ๆ |
| Styling | Tailwind CSS | ใฆใผใใฃใชใใฃใใกใผในใCSS |
| Storage | Local Filesystem | ็ๆ็ปๅใฎไฟๅญ (public/images/generated/) |
sequenceDiagram
participant User
participant ServerAction as Next.js Server Action
participant DB as Supabase DB
participant Background as Background Process
participant Gemini as Google Gemini API
participant LocalFS as Local Filesystem
User->>ServerAction: 1. ่ชฌๆใใญในใ้ไฟก
ServerAction->>DB: 2. Pending็ๆใฌใณใผใไฝๆ
ServerAction->>Background: 3. ้ๅๆใง็ปๅ็ๆ้ๅง
Background->>Gemini: 4. Prompt้ไฟก
Gemini->>Background: 5. ็ปๅใใผใฟ่ฟๅด (Base64)
Background->>LocalFS: 6. ็ปๅไฟๅญ
Background->>DB: 7. ใกใฟใใผใฟๆดๆฐ (completed)
User->>DB: 8. ใใผใชใณใฐใง็ถๆ
็ขบ่ช
DB->>User: 9. ๅฎๆ็ปๅใจใกใฟใใผใฟ่ฟๅด
generations ใใผใใซ - ่ชๅทฑๅ็ งใซใใใใชใผๆง้ ๏ผAdjacency List ใใฟใผใณ๏ผ
| ใซใฉใ ๅ | ๅ | ่ชฌๆ |
|---|---|---|
id |
UUID | ไธปใญใผ๏ผ่ชๅ็ๆ๏ผ |
parent_id |
UUID | ่ฆช็ปๅใฎID๏ผใซใผใใฎๅ ดๅใฏNULL๏ผ |
image_url |
TEXT | ็ๆ็ปๅใฎใญใผใซใซใใน |
prompt |
TEXT | ใฆใผใถใผๅ ฅๅใฎ่ชฌๆๆ |
created_at |
TIMESTAMPTZ | ไฝๆๆฅๆ |
status |
generation_status | ็ๆในใใผใฟใน๏ผpending/completed/failed๏ผ |
RPC้ขๆฐ: get_tree_structure(root_id UUID) - ๅๅธฐ็CTEใซใใๅน็็ใชใใชใผๅๅพ
- Node.js 20ไปฅไธ
- Supabaseใขใซใฆใณใ
- Google Gemini APIใญใผ
- ใชใใธใใชใฎใฏใญใผใณ
git clone https://github.com/kwrkb/visual-echo.git
cd visual-echo- ไพๅญ้ขไฟใฎใคใณในใใผใซ
npm install- ็ฐๅขๅคๆฐใฎ่จญๅฎ
cp .env.local.example .env.local.env.localใ็ทจ้ใใฆใไปฅไธใ่จญๅฎ:
# Supabase่จญๅฎ๏ผProject Settings โ API ใใๅๅพ๏ผ
NEXT_PUBLIC_SUPABASE_URL=your-project-url.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
# Google Gemini API่จญๅฎ๏ผhttps://makersuite.google.com/app/apikey ใใๅๅพ๏ผ
GEMINI_API_KEY=your-gemini-api-key
# ใชใใทใงใณ: ใขใใซๆๅฎ๏ผใใใฉใซใ: gemini-2.5-flash-image๏ผ
GEMINI_MODEL=gemini-2.5-flash-image- ใใผใฟใใผในใฎใปใใใขใใ
Supabase DashboardใฎSQL Editorใงไปฅไธใ้ ็ชใซๅฎ่ก:
-- 1. ในใญใผใใจใใผใใซไฝๆ
-- supabase/schema.sql ใฎๅ
ๅฎนใๅฎ่ก
-- 2. RPC้ขๆฐไฝๆ๏ผๆขๅญDBใฎๅ ดๅใฏไปฅไธใฎใใคใฐใฌใผใทใงใณใๅฎ่ก๏ผ
-- supabase/migrations/add_generation_status_enum.sql
-- supabase/migrations/update_tree_rpc_enum.sqlๆฐ่ฆใปใใใขใใใฎๅ ดๅใฏsupabase/schema.sqlใฎใฟใงOKใงใใ
- ้็บใตใผใใผใฎ่ตทๅ
npm run devhttp://localhost:3000 ใงใขใใชใฑใผใทใงใณใ่ตทๅใใพใใ
/gallery ใซใขใฏใปในใใฆใใฉใณใใ ใซ่กจ็คบใใใ3ๆใฎ็ปๅใใๅฅฝใใชใใฎใ้ธๆใ
้ธๆใใ็ปๅใ่ฆใฆใใใฎๅ ๅฎนใ่ชๅใฎ่จ่ใง่ชฌๆใใพใใ
ใใชใใฎ่ชฌๆใใใจใซใAIใๆฐใใ็ปๅใ็ๆใใพใ๏ผ็ด10ใ30็ง๏ผใ
็ๆใใใ็ปๅใจๅ ใฎ็ปๅใๆฏ่ผใ็ณป่ญใใฅใผใงใใซใผใใใใฎๅค้ทใ็ขบ่ชใงใใพใใ
/tree ใซใขใฏใปในใใฆใใในใฆใฎ็ปๅใฎ้ฃ้ใใคใณใฟใฉใฏใใฃใใชใใชใผใงๆข็ดขใ
- ใฉใณใใ ใซ3ๆใฎ็ปๅใ่กจ็คบ
- ใๅ จใฆ่กจ็คบใใใฟใณใงๅ จ็ปๅไธ่ฆงใซ้ท็งป
- ๅ จ็ปๅใฎ้ฃ้ใๆจๆง้ ใงๅฏ่ฆๅ
- ใบใผใ ใปใใณๆไฝใซๅฏพๅฟ
- ๅใใผใใใฏใชใใฏใใฆ่ฉณ็ดฐใธ้ท็งป
- ็ปๅใฎ็ณป่ญ๏ผใซใผใใใ็พๅจใพใง๏ผใ่กจ็คบ
- ใใญใณใใๅ ฅๅใใฉใผใ ใงๆฐใใๅๅฒใไฝๆ
- ๅญ็ปๅไธ่ฆงใ่กจ็คบ
- ใซใผใ็ปๅ๏ผใใชใผใฎ่ตท็น๏ผใ็ๆ
# ้็บใตใผใใผ่ตทๅ
npm run dev
# ๆฌ็ชใใซใ
npm run build
# ๆฌ็ชใตใผใใผ่ตทๅ
npm start
# Lintใใงใใฏ
npm run lintvisual-echo/
โโโ app/ # Next.js App Router
โ โโโ actions/ # Server Actions
โ โโโ gallery/ # ใฎใฃใฉใชใผใใผใธ็พค
โ โโโ tree/ # ใใชใผใใฅใผ
โ โโโ create/ # ๆฐ่ฆไฝๆใใผใธ
โโโ components/ # Reactใณใณใใผใใณใ
โโโ lib/ # ใฉใคใใฉใชใปใฆใผใใฃใชใใฃ
โ โโโ supabase/ # Supabaseใฏใฉใคใขใณใ
โ โโโ gemini/ # Gemini APIใฏใฉใคใขใณใ
โ โโโ queries/ # ใใผใฟใใผในใฏใจใช
โโโ types/ # TypeScriptๅๅฎ็พฉ
โโโ supabase/ # ใใผใฟใใผใน้ข้ฃ
โ โโโ schema.sql # ในใญใผใๅฎ็พฉ
โ โโโ migrations/ # ใใคใฐใฌใผใทใงใณในใฏใชใใ
โโโ public/ # ้็ใใกใคใซ
โโโ images/
โโโ generated/ # AI็ๆ็ปๅ๏ผgitignoreๅฏพ่ฑก๏ผ
ๆฌใขใใชใฑใผใทใงใณใฏ็ๆใใใ็ปๅใใญใผใซใซใใกใคใซใทในใใ ใซไฟๅญใใพใใๆฌ็ช็ฐๅขใซใใใญใคใใๅ ดๅใฏใSupabase StorageใCloudinaryใชใฉใฎใฏใฉใฆใในใใฌใผใธใธใฎ็งป่กใๅฟ ่ฆใงใใ
Google Gemini APIใฎไฝฟ็จใซใใๆ้ใ็บ็ใใๅฏ่ฝๆงใใใใพใใ่ฉณ็ดฐใฏGemini API Pricingใใ็ขบ่ชใใ ใใใ
้็บ็จใซๅ จใฆใผใถใผใ่ชญใฟๆธใๅฏ่ฝใชRLSใใชใทใผใ่จญๅฎใใใฆใใพใใๆฌ็ช็ฐๅขใงใฏ้ฉๅใช่ช่จผใป่ชๅฏใใชใทใผใ่จญๅฎใใฆใใ ใใใ
MIT License
IssueใปPull Requestใๆญ่ฟใใพใ๏ผ
่ณชๅใๆๆกใใใๅ ดๅใฏใIssuesใงใ็ฅใใใใ ใใใ
Made with โค๏ธ using Next.js, Supabase, and Google Gemini AI
Visual Echo is an asynchronous, branching image association game powered by generative AI.
Describe an image in words, and AI will generate a new image based on your description. Through this chain, you can enjoy the visual evolution that departs from (or miraculously maintains) the original intention.
- ๐ณ Tree Structure: Just like Git branches, multiple interpretations branch out from a single image.
- ๐ Asynchronous Processing: No real-time requirement; play at your own pace.
- ๐ฏ Visualization: Overview the entire chain with an interactive tree view.
- ๐จ AI Generation: High-quality image generation using Google Gemini 2.5 Flash Image.
- ๐ Genealogy Tracking: Track every transition from the image's birth to the present.
Displays 3 randomly selected images. You can start a new chain from each image.
Visualizes the chain of all images in a tree structure. Supports zoom and pan operations.
Visually displays the genealogy of an image (from root to current) and allows adding new interpretations.
| Category | Technology | Usage |
|---|---|---|
| Frontend | Next.js 15 (App Router) | React 19-based full-stack framework |
| Language | TypeScript 5 | Type-safe development environment |
| Database | Supabase (PostgreSQL) | Real-time database |
| AI Model | Google Gemini 2.5 Flash Image | Text-to-Image generation |
| Styling | Tailwind CSS | Utility-first CSS |
| Storage | Local Filesystem | Saving generated images (public/images/generated/) |
sequenceDiagram
participant User
participant ServerAction as Next.js Server Action
participant DB as Supabase DB
participant Background as Background Process
participant Gemini as Google Gemini API
participant LocalFS as Local Filesystem
User->>ServerAction: 1. Send description text
ServerAction->>DB: 2. Create Pending generation record
ServerAction->>Background: 3. Start image generation asynchronously
Background->>Gemini: 4. Send Prompt
Gemini->>Background: 5. Return image data (Base64)
Background->>LocalFS: 6. Save image
Background->>DB: 7. Update metadata (completed)
User->>DB: 8. Check status via polling
DB->>User: 9. Return completed image and metadata
generations table - Tree structure via self-reference (Adjacency List Pattern)
| Column Name | Type | Description |
|---|---|---|
id |
UUID | Primary Key (Auto-generated) |
parent_id |
UUID | Parent Image ID (NULL if root) |
image_url |
TEXT | Local path of the generated image |
prompt |
TEXT | Description entered by the user |
created_at |
TIMESTAMPTZ | Creation timestamp |
status |
generation_status | Generation status (pending/completed/failed) |
RPC Function: get_tree_structure(root_id UUID) - Efficient tree retrieval using Recursive CTE
- Node.js 20 or higher
- Supabase Account
- Google Gemini API Key
- Clone the repository
git clone https://github.com/kwrkb/visual-echo.git
cd visual-echo- Install dependencies
npm install- Set up environment variables
cp .env.local.example .env.localEdit .env.local and set the following:
# Supabase Configuration (Get from Project Settings โ API)
NEXT_PUBLIC_SUPABASE_URL=your-project-url.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=your-anon-key
# Google Gemini API Configuration (Get from https://makersuite.google.com/app/apikey)
GEMINI_API_KEY=your-gemini-api-key
# Optional: Model specification (Default: gemini-2.5-flash-image)
GEMINI_MODEL=gemini-2.5-flash-image- Database Setup
Run the following in order in the Supabase Dashboard SQL Editor:
-- 1. Create schema and tables
-- Execute content of supabase/schema.sql
-- 2. Create RPC functions (Run the following migrations if using an existing DB)
-- supabase/migrations/add_generation_status_enum.sql
-- supabase/migrations/update_tree_rpc_enum.sqlFor a new setup, just supabase/schema.sql is sufficient.
- Start Development Server
npm run devThe application will start at http://localhost:3000.
Access /gallery and select your favorite from 3 randomly displayed images.
Look at the selected image and describe its content in your own words.
Based on your description, AI generates a new image (approx. 10-30 seconds).
Compare the generated image with the original. You can see the transition from the root in the genealogy view.
Access /tree to explore the chains of all images in an interactive tree.
- Displays 3 random images
- "View All" button to transition to the full image list
- Visualizes the chain of all images in a tree structure
- Supports zoom and pan operations
- Click each node to transition to details
- Displays image genealogy (from root to current)
- Prompt input form to create a new branch
- Displays list of child images
- Generates a root image (starting point of a tree)
# Start development server
npm run dev
# Production build
npm run build
# Start production server
npm start
# Lint check
npm run lintvisual-echo/
โโโ app/ # Next.js App Router
โ โโโ actions/ # Server Actions
โ โโโ gallery/ # Gallery pages
โ โโโ tree/ # Tree view
โ โโโ create/ # Creation page
โโโ components/ # React components
โโโ lib/ # Libraries & Utilities
โ โโโ supabase/ # Supabase client
โ โโโ gemini/ # Gemini API client
โ โโโ queries/ # Database queries
โโโ types/ # TypeScript type definitions
โโโ supabase/ # Database related
โ โโโ schema.sql # Schema definition
โ โโโ migrations/ # Migration scripts
โโโ public/ # Static files
โโโ images/
โโโ generated/ # AI generated images (gitignored)
This application saves generated images to the local filesystem. To deploy to a production environment, migration to cloud storage such as Supabase Storage or Cloudinary is required.
Charges may apply for using the Google Gemini API. Please check Gemini API Pricing for details.
For development, an RLS policy allowing read/write for all users is set. Please set appropriate authentication/authorization policies for production.
MIT License
Issues and Pull Requests are welcome!
If you have questions or suggestions, please let us know in Issues.