openfree commited on
Commit
e6bcdc4
·
verified ·
1 Parent(s): 11d9288

Delete app.py

Browse files
Files changed (1) hide show
  1. app.py +0 -650
app.py DELETED
@@ -1,650 +0,0 @@
1
- import os
2
- import gradio as gr
3
- import random
4
- import time
5
- import logging
6
- import google.generativeai as genai
7
-
8
- import torch
9
- import numpy as np
10
- from diffusers import DiffusionPipeline
11
- from transformers import pipeline as hf_pipeline
12
- import re
13
-
14
- ##############################################################################
15
- # 1) ZeroGPU Environment Setup + Device and Dtype Configuration
16
- ##############################################################################
17
- try:
18
- import zerogpu
19
- zerogpu.init()
20
- print("ZeroGPU initialized successfully")
21
- device = "cuda" if torch.cuda.is_available() else "cpu"
22
- except ImportError:
23
- print("ZeroGPU package not installed, continuing without it")
24
- if os.getenv("ZERO_GPU"):
25
- print("ZeroGPU environment variable is set but zerogpu package is not installed.")
26
- device = "cuda" if torch.cuda.is_available() else "cpu"
27
- except Exception as e:
28
- print(f"Error initializing ZeroGPU: {e}")
29
- print("Continuing without ZeroGPU")
30
- device = "cuda" if torch.cuda.is_available() else "cpu"
31
-
32
- dtype = torch.bfloat16 if device == "cuda" else torch.float32
33
-
34
- print(f"Using device: {device}, dtype: {dtype}")
35
-
36
- ##############################################################################
37
- # 2) Load Models: Translation Model, Diffusion Pipeline
38
- ##############################################################################
39
- try:
40
- translator = hf_pipeline(
41
- "translation",
42
- model="Helsinki-NLP/opus-mt-ko-en",
43
- device=0 if device == "cuda" else -1
44
- )
45
-
46
- pipe = DiffusionPipeline.from_pretrained(
47
- "black-forest-labs/FLUX.1-schnell",
48
- torch_dtype=dtype
49
- ).to(device)
50
-
51
- print("Models loaded successfully")
52
- except Exception as e:
53
- print(f"Error loading models: {e}")
54
- def dummy_translator(text):
55
- return [{'translation_text': text}]
56
-
57
- class DummyPipe:
58
- def __call__(self, **kwargs):
59
- from PIL import Image
60
- import numpy as np
61
- dummy_img = Image.fromarray(np.zeros((512, 512, 3), dtype=np.uint8))
62
- class DummyResult:
63
- def __init__(self, img):
64
- self.images = [img]
65
- return DummyResult(dummy_img)
66
-
67
- translator = dummy_translator
68
- pipe = DummyPipe()
69
-
70
- MAX_SEED = np.iinfo(np.int32).max
71
- MAX_IMAGE_SIZE = 2048
72
-
73
- ##############################################################################
74
- # Korean detection and input text cleaning functions
75
- ##############################################################################
76
- def contains_korean(text):
77
- for char in text:
78
- if ord('가') <= ord(char) <= ord('힣'):
79
- return True
80
- return False
81
-
82
- def clean_input_text(text):
83
- """
84
- Allows only Korean, English, numbers, whitespace and common punctuation marks.
85
- Adjust allowed characters as needed.
86
- """
87
- allowed = re.compile(r'[^ㄱ-ㅎ가-힣a-zA-Z0-9\s\.\,\!\?\-\:\;\'\"]')
88
- cleaned_text = allowed.sub('', text)
89
- return cleaned_text
90
-
91
- def log_unexpected_characters(text):
92
- allowed = re.compile(r'[ㄱ-ㅎ가-힣a-zA-Z0-9\s\.\,\!\?\-\:\;\'\"]')
93
- unexpected_chars = [char for char in text if not allowed.match(char)]
94
- if unexpected_chars:
95
- print("Unexpected characters found:", set(unexpected_chars))
96
- else:
97
- print("No unexpected characters in the input text.")
98
-
99
- ##############################################################################
100
- # Image Generation Function
101
- ##############################################################################
102
- def generate_design_image(prompt, seed=42, randomize_seed=True, width=1024, height=1024, num_inference_steps=4):
103
- original_prompt = prompt
104
- translated = False
105
-
106
- # Clean the input text
107
- prompt = clean_input_text(prompt)
108
-
109
- # Pre-process: if input is too long, trim to 1000 characters
110
- if len(prompt) > 1000:
111
- prompt = prompt[:1000]
112
-
113
- if contains_korean(prompt):
114
- # When calling translation, add max_length and truncation options to avoid length issues
115
- translation = translator(prompt, max_length=400, truncation=True)
116
- prompt = translation[0]['translation_text']
117
- translated = True
118
-
119
- if randomize_seed:
120
- seed = random.randint(0, MAX_SEED)
121
-
122
- generator = torch.Generator(device=device).manual_seed(seed)
123
-
124
- image = pipe(
125
- prompt=prompt,
126
- width=width,
127
- height=height,
128
- num_inference_steps=num_inference_steps,
129
- generator=generator,
130
- guidance_scale=0.0
131
- ).images[0]
132
-
133
- return image
134
-
135
- ##############################################################################
136
- # Logging Setup
137
- ##############################################################################
138
- logging.basicConfig(
139
- level=logging.INFO,
140
- format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
141
- handlers=[
142
- logging.FileHandler("api_debug.log"),
143
- logging.StreamHandler()
144
- ]
145
- )
146
- logger = logging.getLogger("idea_generator")
147
-
148
- ##############################################################################
149
- # Gemini API Key
150
- ##############################################################################
151
- GEMINI_API_KEY = os.getenv("GEMINI_API_KEY")
152
- genai.configure(api_key=GEMINI_API_KEY)
153
-
154
- ##############################################################################
155
- # Optional Transformation Choice Function
156
- ##############################################################################
157
- def choose_alternative(transformation):
158
- if "/" not in transformation:
159
- return transformation
160
- parts = transformation.split("/")
161
- if len(parts) != 2:
162
- return random.choice([part.strip() for part in parts])
163
- left = parts[0].strip()
164
- right = parts[1].strip()
165
- if " " in left:
166
- tokens = left.split(" ", 1)
167
- prefix = tokens[0]
168
- if not right.startswith(prefix):
169
- option1 = left
170
- option2 = prefix + " " + right
171
- else:
172
- option1 = left
173
- option2 = right
174
- return random.choice([option1, option2])
175
- else:
176
- return random.choice([left, right])
177
-
178
- ##############################################################################
179
- # Transformation Categories Dictionaries
180
- ##############################################################################
181
- # Korean version
182
- physical_transformation_categories = {
183
- "센서 기능": [
184
- "시각 센서/감지", "청각 센서/감지", "촉각 센서/감지", "미각 센서/감지", "후각 센서/감지",
185
- "온도 센서/감지", "습도 센서/감지", "압력 센서/감지", "가속도 센서/감지", "회전 센서/감지",
186
- "근접 센서/감지", "위치 센서/감지", "운동 센서/감지", "가스 센서/감지", "적외선 센서/감지",
187
- "자외선 센서/감지", "방사선 센서/감지", "자기장 센서/감지", "전기장 센서/감지", "화학물질 센서/감지",
188
- "생체신호 센서/감지", "진동 센서/감지", "소음 센서/감지", "빛 세기 센서/감지", "빛 파장 센서/감지",
189
- "기울기 센서/감지", "pH 센서/감지", "전류 센서/감지", "전압 센서/감지", "이미지 센서/감지",
190
- "거리 센서/감지", "깊이 센서/감지", "중력 센서/감지", "속도 센서/감지", "흐름 센서/감지",
191
- "수위 센서/감지", "탁도 센서/감지", "염도 센서/감지", "금속 감지", "압전 센서/감지",
192
- "광전 센서/감지", "열전대 센서/감지", "홀 효과 센서/감지", "초음파 센서/감지", "레이더 센서/감지",
193
- "라이다 센서/감지", "터치 센서/감지", "제스처 센서/감지", "심박 센서/감지", "혈압 센서/감지"
194
- ],
195
- "크기와 형태 변화": [
196
- "부피 늘어남/줄어듦", "길이 늘어남/줄어듦", "너비 늘어남/줄어듦", "높이 늘어남/줄어듦",
197
- "밀도 변화", "무게 증가/감소", "모양 변형", "상태 변화", "불균등 변형",
198
- "복잡한 형태 변형", "비틀림/꼬임", "불균일한 확장/축소", "모서리 둥글게/날카롭게",
199
- "깨짐/갈라짐", "여러 조각 나눠짐", "물 저항", "먼지 저항", "찌그러짐/복원",
200
- "접힘/펼쳐짐", "압착/팽창", "늘어남/수축", "구겨짐/평평해짐", "뭉개짐/단단해짐",
201
- "말림/펴짐", "꺾임/구부러짐"
202
- ],
203
- "표면 및 외관 변화": [
204
- "색상 변화", "질감 변화", "투명/불투명 변화", "반짝임/무광 변화",
205
- "빛 반사 정도 변화", "무늬 변화", "각도에 따른 색상 변화", "빛에 따른 색상 변화",
206
- "온도에 따른 색상 변화", "홀로그램 효과", "표면 각도별 빛 반사", "표면 모양 변형",
207
- "초미세 표면 구조 변화", "자가 세정 효과", "얼룩/패턴 생성", "흐림/선명함 변화",
208
- "광택/윤기 변화", "색조/채도 변화", "발광/형광", "빛 산란 효과",
209
- "빛 흡수 변화", "반투명 효과", "그림자 효과 변화", "자외선 반응 변화",
210
- "야광 효과"
211
- ],
212
- "물질의 상태 변화": [
213
- "고체/액체/기체 전환", "결정화/용해", "산화/부식", "딱딱해짐/부드러워짐",
214
- "특수 상태 전환", "무정형/결정형 전환", "성분 분리", "미세 입자 형성/분해",
215
- "젤 형성/풀어짐", "준안정 상태 변화", "분자 자가 정렬/분해", "상태변화 지연 현상",
216
- "녹음", "굳음", "증발/응축", "승화/증착", "침전/부유", "분산/응집",
217
- "건조/습윤", "팽윤/수축", "동결/해동", "풍화/침식", "충전/방전",
218
- "결합/분리", "발효/부패"
219
- ],
220
- "움직임 특성 변화": [
221
- "가속/감속", "일정 속도 유지", "진동/진동 감소", "부딪힘/튕김",
222
- "회전 속도 증가/감소", "회전 방향 변화", "불규칙 움직임", "멈췄다 미끄러지는 현상",
223
- "공진/반공진", "유체 속 저항/양�� 변화", "움직임 저항 변화", "복합 진동 움직임",
224
- "특수 유체 속 움직임", "회전-이동 연계 움직임", "관성 정지", "충격 흡수",
225
- "충격 전달", "운동량 보존", "마찰력 변화", "관성 탈출", "불안정 균형",
226
- "동적 안정성", "흔들림 감쇠", "경로 예측성", "회피 움직임"
227
- ],
228
- "구조적 변화": [
229
- "부품 추가/제거", "조립/분해", "접기/펴기", "변형/원상복구", "최적 구조 변화",
230
- "자가 재배열", "자연 패턴 형성/소멸", "규칙적 패턴 변화", "모듈식 변형",
231
- "복잡성 증가 구조", "원래 모양 기억 효과", "시간에 따른 형태 변화", "부분 제거",
232
- "부분 교체", "결합", "분리", "분할/통합", "중첩/겹침", "내부 구조 변화",
233
- "외부 구조 변화", "중심축 이동", "균형점 변화", "계층 구조 변화", "지지 구조 변화",
234
- "응력 분산 구조", "충격 흡수 구조", "그리드/매트릭스 구조 변화", "상호 연결성 변화"
235
- ],
236
- "공간 이동": [
237
- "앞/뒤 이동", "좌/우 이동", "위/아래 이동", "세로축 회전(고개 끄덕임)",
238
- "가로축 회전(고개 젓기)", "길이축 회전(옆으로 기울임)", "원 운동", "나선형 이동",
239
- "관성에 의한 미끄러짐", "회전축 변화", "불규칙 회전", "흔들림 운동", "포물선 이동",
240
- "무중력 부유", "수면 위 부유", "점프/도약", "슬라이딩", "롤링", "자유 낙하",
241
- "왕복 운동", "탄성 튕김", "관통", "회피 움직임", "지그재그 이동", "스윙 운동"
242
- ],
243
- "시간 관련 변화": [
244
- "노화/풍화", "마모/부식", "색 바램/변색", "손상/회복", "수명 주기 변화",
245
- "사용자 상호작용에 따른 적응", "학습 기반 형태 최적화", "시간에 따른 물성 변화",
246
- "집단 기억 효과", "문화적 의미 변화", "지연 반응", "이전 상태 의존 변화",
247
- "점진적 시간 변화", "진화적 변화", "주기적 재생", "계절 변화 적응",
248
- "생체리듬 변화", "생애 주기 단계", "성장/퇴화", "자기 복구/재생",
249
- "자연 순환 적응", "지속성/일시성", "기억 효과", "지연된 작용", "누적 효과"
250
- ],
251
- "빛과 시각 효과": [
252
- "발광/소등", "빛 투과/차단", "빛 산란/집중", "색상 스펙트럼 변화", "빛 회절",
253
- "빛 간섭", "홀로그램 생성", "레이저 효과", "빛 편광", "형광/인광",
254
- "자외선/적외선 발광", "광학적 착시", "빛 굴절", "그림자 생성/제거",
255
- "색수차 효과", "무지개 효과", "글로우 효과", "플래시 효과", "조명 패턴",
256
- "빔 효과", "광 필터 효과", "빛의 방향성 변화", "투영 효과", "빛 감지/반응",
257
- "광도 변화"
258
- ],
259
- "소리와 진동 효과": [
260
- "소리 발생/소멸", "소리 높낮이 변화", "소리 크기 변화", "음색 변화",
261
- "공명/반공명", "음향 진동", "초음파/저음파 발생", "음향 집중/분산",
262
- "음향 반사/흡수", "음향 도플러 효과", "음파 간섭", "음향 공진",
263
- "진동 패턴 변화", "타악 효과", "음향 피드백", "음향 차폐/증폭",
264
- "소리 지향성", "음향 왜곡", "비트 생성", "하모닉스 생성", "주파수 변조",
265
- "음향 충격파", "음향 필터링"
266
- ]
267
- }
268
-
269
- ##############################################################################
270
- # Gemini API Call Function (Language Independent)
271
- ##############################################################################
272
- def query_gemini_api(prompt):
273
- try:
274
- model = genai.GenerativeModel('gemini-2.0-flash-thinking-exp-01-21')
275
- response = model.generate_content(prompt)
276
- try:
277
- if hasattr(response, 'text'):
278
- return response.text
279
- if hasattr(response, 'candidates') and response.candidates:
280
- candidate = response.candidates[0]
281
- if hasattr(candidate, 'content'):
282
- content = candidate.content
283
- if hasattr(content, 'parts') and content.parts:
284
- if len(content.parts) > 0:
285
- return content.parts[0].text
286
- if hasattr(response, 'parts') and response.parts:
287
- if len(response.parts) > 0:
288
- return response.parts[0].text
289
- return "Unable to generate a response. API response structure is different than expected."
290
- except Exception as inner_e:
291
- logger.error(f"Error processing response: {inner_e}")
292
- return f"An error occurred while processing the response: {str(inner_e)}"
293
- except Exception as e:
294
- logger.error(f"Error calling Gemini API: {e}")
295
- if "API key not valid" in str(e):
296
- return "API key is not valid. Please check your GEMINI_API_KEY environment variable."
297
- return f"An error occurred while calling the API: {str(e)}"
298
-
299
- ##############################################################################
300
- # Description Expansion Functions (LLM) - Korean and English Versions
301
- ##############################################################################
302
- def enhance_with_llm(base_description, obj_name, category):
303
- prompt = f"""
304
- 다음은 '{obj_name}'의 '{category}' 관련 간단한 설명입니다:
305
- "{base_description}"
306
- 위 내용을 보다 구체화하여,
307
- 1) 창의적인 모델/컨셉/형상의 변화에 대한 이해,
308
- 2) 혁신 포인트와 기능성 등을 중심으로
309
- 3~4문장의 아이디어로 확장해 주세요.
310
- """
311
- return query_gemini_api(prompt)
312
-
313
- def enhance_with_llm_en(base_description, obj_name, category):
314
- prompt = f"""
315
- Below is a brief description related to '{category}' for '{obj_name}':
316
- "{base_description}"
317
- Please expand the above content into a more detailed explanation, focusing on:
318
- 1) Creative transformation of the model/concept/shape,
319
- 2) Innovative aspects and functionality,
320
- in 3-4 sentences.
321
- """
322
- return query_gemini_api(prompt)
323
-
324
- ##############################################################################
325
- # Transformation Idea Generation Functions for Both Languages
326
- ##############################################################################
327
- def generate_single_object_transformation_for_category_lang(obj, selected_category, categories_dict, lang="ko"):
328
- transformations = categories_dict.get(selected_category)
329
- if not transformations:
330
- return {}
331
- transformation = choose_alternative(random.choice(transformations))
332
- if lang == "ko":
333
- base_description = f"{obj}이(가) {transformation} 현상을 보인다"
334
- else:
335
- base_description = f"{obj} exhibits {transformation}"
336
- return {selected_category: {"base": base_description, "enhanced": None}}
337
-
338
- def generate_two_objects_interaction_for_category_lang(obj1, obj2, selected_category, categories_dict, lang="ko"):
339
- transformations = categories_dict.get(selected_category)
340
- if not transformations:
341
- return {}
342
- transformation = choose_alternative(random.choice(transformations))
343
- if lang == "ko":
344
- template = random.choice([
345
- "{obj1}이(가) {obj2}에 결합하여 {change}가 발생했다",
346
- "{obj1}과(와) {obj2}이(가) 충돌하면서 {change}가 일어났다"
347
- ])
348
- else:
349
- template = random.choice([
350
- "{obj1} combined with {obj2} resulted in {change}",
351
- "A collision between {obj1} and {obj2} led to {change}"
352
- ])
353
- base_description = template.format(obj1=obj1, obj2=obj2, change=transformation)
354
- return {selected_category: {"base": base_description, "enhanced": None}}
355
-
356
- def generate_three_objects_interaction_for_category_lang(obj1, obj2, obj3, selected_category, categories_dict, lang="ko"):
357
- transformations = categories_dict.get(selected_category)
358
- if not transformations:
359
- return {}
360
- transformation = choose_alternative(random.choice(transformations))
361
- if lang == "ko":
362
- template = random.choice([
363
- "{obj1}, {obj2}, {obj3}이(가) 삼각형 구조로 결합하여 {change}가 발생했다",
364
- "{obj1}이(가) {obj2}와(과) {obj3} 사이에서 매개체 역할을 하며 {change}를 촉진했다"
365
- ])
366
- else:
367
- template = random.choice([
368
- "{obj1}, {obj2}, and {obj3} formed a triangular structure resulting in {change}",
369
- "{obj1} acted as an intermediary between {obj2} and {obj3}, facilitating {change}"
370
- ])
371
- base_description = template.format(obj1=obj1, obj2=obj2, obj3=obj3, change=transformation)
372
- return {selected_category: {"base": base_description, "enhanced": None}}
373
-
374
- def enhance_descriptions_lang(results, objects, lang="ko"):
375
- obj_name = " 및 ".join([obj for obj in objects if obj]) if lang=="ko" else " and ".join([obj for obj in objects if obj])
376
- for category, result in results.items():
377
- if lang == "ko":
378
- result["enhanced"] = enhance_with_llm(result["base"], obj_name, category)
379
- else:
380
- result["enhanced"] = enhance_with_llm_en(result["base"], obj_name, category)
381
- return results
382
-
383
- def generate_transformations_lang(text1, text2, text3, selected_category, categories_dict, lang="ko"):
384
- if text2 and text3:
385
- results = generate_three_objects_interaction_for_category_lang(text1, text2, text3, selected_category, categories_dict, lang)
386
- objects = [text1, text2, text3]
387
- elif text2:
388
- results = generate_two_objects_interaction_for_category_lang(text1, text2, selected_category, categories_dict, lang)
389
- objects = [text1, text2]
390
- else:
391
- results = generate_single_object_transformation_for_category_lang(text1, selected_category, categories_dict, lang)
392
- objects = [text1]
393
- return enhance_descriptions_lang(results, objects, lang)
394
-
395
- def format_results_lang(results, lang="ko"):
396
- formatted = ""
397
- if lang == "ko":
398
- for category, result in results.items():
399
- formatted += f"## {category}\n**기본 아이디어**: {result['base']}\n\n**확장된 아이디어**: {result['enhanced']}\n\n---\n\n"
400
- else:
401
- for category, result in results.items():
402
- formatted += f"## {category}\n**Base Idea**: {result['base']}\n\n**Expanded Idea**: {result['enhanced']}\n\n---\n\n"
403
- return formatted
404
-
405
- def process_inputs_lang(text1, text2, text3, selected_category, categories_dict, lang="ko", progress=gr.Progress()):
406
- text1 = text1.strip() if text1 else None
407
- text2 = text2.strip() if text2 else None
408
- text3 = text3.strip() if text3 else None
409
-
410
- if not text1:
411
- return "오류: 최소 하나의 키워드를 입력해주세요." if lang=="ko" else "Error: Please enter at least one keyword."
412
-
413
- if lang == "ko":
414
- progress(0.05, desc="아이디어 생성 준비 중...")
415
- time.sleep(0.3)
416
- progress(0.1, desc="창의적인 아이디어 생성 시작...")
417
- else:
418
- progress(0.05, desc="Preparing idea generation...")
419
- time.sleep(0.3)
420
- progress(0.1, desc="Generating creative idea...")
421
-
422
- results = generate_transformations_lang(text1, text2, text3, selected_category, categories_dict, lang)
423
-
424
- if lang == "ko":
425
- progress(0.8, desc="결과 포맷팅 중...")
426
- formatted = format_results_lang(results, lang)
427
- progress(1.0, desc="완료!")
428
- else:
429
- progress(0.8, desc="Formatting results...")
430
- formatted = format_results_lang(results, lang)
431
- progress(1.0, desc="Done!")
432
- return formatted
433
-
434
- def process_all_lang(text1, text2, text3, selected_category, categories_dict, lang="ko", progress=gr.Progress()):
435
- idea_result = process_inputs_lang(text1, text2, text3, selected_category, categories_dict, lang, progress)
436
- image_result = generate_design_image(
437
- idea_result,
438
- seed=42,
439
- randomize_seed=True,
440
- width=1024,
441
- height=1024,
442
- num_inference_steps=4
443
- )
444
- return idea_result, image_result
445
-
446
- ##############################################################################
447
- # Warning Message Function for API Key (Language Specific)
448
- ##############################################################################
449
- def get_warning_message_lang(lang="ko"):
450
- if not GEMINI_API_KEY:
451
- return "⚠️ 환경 변수 GEMINI_API_KEY가 설정되지 않았습니다. Gemini API 키를 설정하세요." if lang=="ko" else "⚠️ The GEMINI_API_KEY environment variable is not set. Please set your Gemini API key."
452
- return ""
453
-
454
- ##############################################################################
455
- # Helper function for caching examples in the English tab
456
- ##############################################################################
457
- def process_all_lang_example(text1, text2, text3, selected_category):
458
- # 고정된 state값(physical_transformation_categories_en, "en")으로 호출
459
- return process_all_lang(text1, text2, text3, selected_category, physical_transformation_categories_en, "en")
460
-
461
- ##############################################################################
462
- # Gradio UI with Two Tabs: English (Main Home) and Korean
463
- ##############################################################################
464
- with gr.Blocks(
465
- title="Idea Transformer",
466
- theme=gr.themes.Soft(primary_hue="teal", secondary_hue="slate", neutral_hue="neutral")
467
- ) as demo:
468
-
469
- gr.HTML("""
470
- <style>
471
- body {
472
- background: linear-gradient(135deg, #e0eafc, #cfdef3);
473
- font-family: 'Arial', sans-serif;
474
- }
475
- .gradio-container {
476
- padding: 20px;
477
- }
478
- h1, h2 {
479
- text-align: center;
480
- }
481
- h1 {
482
- color: #333;
483
- }
484
- h2 {
485
- color: #555;
486
- }
487
- .output {
488
- background-color: #ffffff;
489
- padding: 15px;
490
- border-radius: 8px;
491
- }
492
- .gr-button {
493
- background-color: #4CAF50;
494
- color: white;
495
- border: none;
496
- border-radius: 4px;
497
- padding: 8px 16px;
498
- }
499
- .progress-message {
500
- color: #2196F3;
501
- font-weight: bold;
502
- margin-top: 10px;
503
- }
504
- </style>
505
- """)
506
-
507
- with gr.Tabs():
508
- with gr.Tab(label="English"):
509
- gr.Markdown("# 🚀 Idea Transformer")
510
- gr.Markdown("Based on up to **three keywords** and a **selected category**, this tool generates a creative transformation idea and a design image using the expanded idea as a prompt.")
511
-
512
- warning_en = gr.Markdown(get_warning_message_lang("en"))
513
-
514
- with gr.Row():
515
- with gr.Column(scale=1):
516
- text_input1_en = gr.Textbox(label="Keyword 1 (required)", placeholder="e.g., Smartphone")
517
- text_input2_en = gr.Textbox(label="Keyword 2 (optional)", placeholder="e.g., Artificial Intelligence")
518
- text_input3_en = gr.Textbox(label="Keyword 3 (optional)", placeholder="e.g., Healthcare")
519
- category_radio_en = gr.Radio(
520
- label="Select Category",
521
- choices=list(physical_transformation_categories_en.keys()),
522
- value=list(physical_transformation_categories_en.keys())[0],
523
- info="Select a category."
524
- )
525
- status_msg_en = gr.Markdown("💡 Click the 'Generate Idea' button to create an idea and design image based on the selected category.")
526
-
527
- processing_indicator_en = gr.HTML("""
528
- <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
529
- <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>
530
- <p style="margin-left: 10px; font-weight: bold; color: #3498db;">Processing...</p>
531
- </div>
532
- <style>
533
- @keyframes spin {
534
- 0% { transform: rotate(0deg); }
535
- 100% { transform: rotate(360deg); }
536
- }
537
- </style>
538
- """, visible=False)
539
-
540
- submit_button_en = gr.Button("Generate Idea", variant="primary")
541
-
542
- with gr.Column(scale=2):
543
- idea_output_en = gr.Markdown(label="Idea Output")
544
- generated_image_en = gr.Image(label="Generated Design Image", type="pil")
545
-
546
- gr.Examples(
547
- examples=[
548
- ["Smartphone", "", "", "Sensor Functions"],
549
- ["Car", "", "", "Size and Shape Change"],
550
- ["Car", "Artificial Intelligence", "", "Surface and Appearance Change"],
551
- ["Drone", "Artificial Intelligence", "", "Material State Change"],
552
- ["Sneakers", "Wearable", "Health", "Structural Change"],
553
- ],
554
- inputs=[text_input1_en, text_input2_en, text_input3_en, category_radio_en],
555
- fn=process_all_lang_example,
556
- outputs=[idea_output_en, generated_image_en],
557
- cache_examples=True
558
- )
559
-
560
- def show_processing_indicator_en():
561
- return gr.update(visible=True)
562
-
563
- def hide_processing_indicator_en():
564
- return gr.update(visible=False)
565
-
566
- submit_button_en.click(
567
- fn=show_processing_indicator_en,
568
- inputs=None,
569
- outputs=processing_indicator_en
570
- ).then(
571
- fn=process_all_lang,
572
- inputs=[text_input1_en, text_input2_en, text_input3_en, category_radio_en, gr.State(physical_transformation_categories_en), gr.State("en")],
573
- outputs=[idea_output_en, generated_image_en]
574
- ).then(
575
- fn=hide_processing_indicator_en,
576
- inputs=None,
577
- outputs=processing_indicator_en
578
- )
579
-
580
- with gr.Tab(label="한국어"):
581
- gr.Markdown("# 🚀 아이디어 트랜스포머")
582
- gr.Markdown("입력한 **키워드**(최대 3개)와 **카테고리**를 바탕으로, 창의적인 모델/컨셉/형상 변화 아이디어를 생성하고, 해당 확장 아이디어를 프롬프트로 하여 디자인 이미지를 생성합니다.")
583
-
584
- warning_ko = gr.Markdown(get_warning_message_lang("ko"))
585
-
586
- with gr.Row():
587
- with gr.Column(scale=1):
588
- text_input1_ko = gr.Textbox(label="키워드 1 (필수)", placeholder="예: 스마트폰")
589
- text_input2_ko = gr.Textbox(label="키워드 2 (선택)", placeholder="예: 인공지능")
590
- text_input3_ko = gr.Textbox(label="키워드 3 (선택)", placeholder="예: 헬스케어")
591
- category_radio_ko = gr.Radio(
592
- label="카테고리 선택",
593
- choices=list(physical_transformation_categories.keys()),
594
- value=list(physical_transformation_categories.keys())[0],
595
- info="출력할 카테고리를 선택하세요."
596
- )
597
- status_msg_ko = gr.Markdown("💡 '아이디어 생성하기' 버튼을 클릭하면 선택한 카테고리에 해당하는 아이디어와 디자인 이미지가 생성됩니다.")
598
-
599
- processing_indicator_ko = gr.HTML("""
600
- <div style="display: flex; justify-content: center; align-items: center; margin: 10px 0;">
601
- <div style="border: 5px solid #f3f3f3; border-top: 5px solid #3498db; border-radius: 50%; width: 30px; height: 30px; animation: spin 2s linear infinite;"></div>
602
- <p style="margin-left: 10px; font-weight: bold; color: #3498db;">처리 중입니다...</p>
603
- </div>
604
- <style>
605
- @keyframes spin {
606
- 0% { transform: rotate(0deg); }
607
- 100% { transform: rotate(360deg); }
608
- }
609
- </style>
610
- """, visible=False)
611
-
612
- submit_button_ko = gr.Button("아이디어 생성하기", variant="primary")
613
-
614
- with gr.Column(scale=2):
615
- idea_output_ko = gr.Markdown(label="아이디어 결과")
616
- generated_image_ko = gr.Image(label="생성된 디자인 이미지", type="pil")
617
-
618
- gr.Examples(
619
- examples=[
620
- ["스마트폰", "", "", "센서 기능"],
621
- ["자동차", "", "", "크기와 형태 변화"],
622
- ["자동차", "인공지능", "", "표면 및 외관 변화"],
623
- ["드론", "인공지능", "", "물질의 상태 변화"],
624
- ["운동화", "웨어러블", "건강", "구조적 변화"],
625
- ],
626
- inputs=[text_input1_ko, text_input2_ko, text_input3_ko, category_radio_ko]
627
- )
628
-
629
- def show_processing_indicator_ko():
630
- return gr.update(visible=True)
631
-
632
- def hide_processing_indicator_ko():
633
- return gr.update(visible=False)
634
-
635
- submit_button_ko.click(
636
- fn=show_processing_indicator_ko,
637
- inputs=None,
638
- outputs=processing_indicator_ko
639
- ).then(
640
- fn=process_all_lang,
641
- inputs=[text_input1_ko, text_input2_ko, text_input3_ko, category_radio_ko, gr.State(physical_transformation_categories), gr.State("ko")],
642
- outputs=[idea_output_ko, generated_image_ko]
643
- ).then(
644
- fn=hide_processing_indicator_ko,
645
- inputs=None,
646
- outputs=processing_indicator_ko
647
- )
648
-
649
- if __name__ == "__main__":
650
- demo.launch(debug=True)