AkashKumarave commited on
Commit
f750405
·
verified ·
1 Parent(s): 22fcb4a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +57 -84
app.py CHANGED
@@ -1,23 +1,15 @@
1
  import gradio as gr
2
  import requests
3
  import base64
4
- import os
5
  import time
6
  import jwt
7
- import logging
8
  from pathlib import Path
9
 
10
- # Configure logging
11
- logging.basicConfig(level=logging.INFO)
12
- logger = logging.getLogger(__name__)
13
-
14
- # ===== API CONFIGURATION =====
15
  ACCESS_KEY_ID = "AFyHfnQATghFdCMyAG3gRPbNY4TNKFGB"
16
  ACCESS_KEY_SECRET = "TTepeLyBterLNM3brYPGmdndBnnyKJBA"
17
- API_BASE_URL = "https://api-singapore.klingai.com"
18
- CREATE_TASK_ENDPOINT = f"{API_BASE_URL}/v1/images/generations" # SINGLE image endpoint
19
 
20
- # ===== AUTHENTICATION =====
21
  def generate_jwt_token():
22
  payload = {
23
  "iss": ACCESS_KEY_ID,
@@ -26,74 +18,49 @@ def generate_jwt_token():
26
  }
27
  return jwt.encode(payload, ACCESS_KEY_SECRET, algorithm="HS256")
28
 
29
- # ===== IMAGE PROCESSING =====
30
- def prepare_image_base64(image_path):
31
- """Convert image to base64 without prefix"""
32
- with open(image_path, "rb") as img_file:
33
- return base64.b64encode(img_file.read()).decode('utf-8')
34
-
35
- # ===== API CALLS =====
36
- def create_face_transform_task(image_base64, prompt):
37
- headers = {
38
- "Authorization": f"Bearer {generate_jwt_token()}",
39
- "Content-Type": "application/json"
40
- }
41
-
42
- payload = {
43
- "model_name": "kling-v2", # Best for face transformation
44
- "prompt": prompt,
45
- "image": image_base64,
46
- "image_reference": "face", # Critical for face transformation
47
- "image_fidelity": 0.97, # 97% face similarity
48
- "human_fidelity": 0.95, # High facial feature preservation
49
- "aspect_ratio": "1:1"
50
- }
51
-
52
- try:
53
- response = requests.post(CREATE_TASK_ENDPOINT, json=payload, headers=headers)
54
- response.raise_for_status()
55
- return response.json()
56
- except Exception as e:
57
- logger.error(f"API Error: {str(e)}")
58
- return None
59
-
60
- def check_task_status(task_id):
61
- headers = {"Authorization": f"Bearer {generate_jwt_token()}"}
62
- try:
63
- response = requests.get(f"{API_BASE_URL}/v1/images/generations/{task_id}", headers=headers)
64
- response.raise_for_status()
65
- return response.json()
66
- except Exception as e:
67
- logger.error(f"Status Check Error: {str(e)}")
68
- return None
69
-
70
- # ===== MAIN FUNCTION =====
71
  def transform_face(image_path, prompt):
72
- if not image_path:
73
- return None, "Please upload an image first"
74
-
75
  try:
76
- # Prepare image
77
- image_base64 = prepare_image_base64(image_path)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
78
 
79
  # Create task
80
- task_data = create_face_transform_task(image_base64, prompt)
81
- if not task_data or task_data.get("code") != 0:
82
- return None, "Failed to start transformation"
83
 
84
- task_id = task_data["data"]["task_id"]
85
 
86
- # Poll for results (max 2 minutes)
87
  for _ in range(12):
88
  time.sleep(10)
89
- status_data = check_task_status(task_id)
90
- if not status_data:
91
- continue
92
-
 
 
93
  if status_data["data"]["task_status"] == "succeed":
94
  image_url = status_data["data"]["task_result"]["images"][0]["url"]
95
  img_data = requests.get(image_url).content
96
- output_path = f"/tmp/transformed_face_{task_id}.png"
97
  with open(output_path, "wb") as f:
98
  f.write(img_data)
99
  return output_path, None
@@ -103,37 +70,43 @@ def transform_face(image_path, prompt):
103
  except Exception as e:
104
  return None, f"Error: {str(e)}"
105
 
106
- # ===== GRADIO INTERFACE =====
107
- with gr.Blocks() as app:
108
- gr.Markdown("# 🎭 Face Transformation")
109
- gr.Markdown("Upload a clear face photo and describe your transformation")
110
 
111
  with gr.Row():
112
  with gr.Column():
113
- image_input = gr.Image(type="filepath", label="Upload Face Photo", sources=["upload"])
 
 
 
 
 
114
  prompt_input = gr.Textbox(
115
- label="Transformation Prompt",
116
- placeholder="e.g. 'cyberpunk character', 'renaissance painting'"
117
  )
118
- generate_btn = gr.Button("Transform", variant="primary")
119
 
120
  gr.Markdown("### Requirements")
121
  gr.Markdown("""
122
- - Clear frontal face photo
123
- - Single person only
124
- - Max 10MB size (JPG/PNG)
125
- - Min 300x300 resolution
 
126
  """)
127
 
128
  with gr.Column():
129
- output_image = gr.Image(label="Transformed Result", interactive=False)
130
  output_file = gr.File(label="Download")
131
- status_output = gr.Textbox(label="Status", interactive=False)
132
 
133
  generate_btn.click(
134
- fn=lambda img, prompt: transform_face(img, prompt) + (None,), # Extra None for error placeholder
135
- inputs=[image_input, prompt_input],
136
- outputs=[output_image, output_file, status_output]
137
  )
138
 
139
  if __name__ == "__main__":
 
1
  import gradio as gr
2
  import requests
3
  import base64
 
4
  import time
5
  import jwt
 
6
  from pathlib import Path
7
 
8
+ # Configuration
 
 
 
 
9
  ACCESS_KEY_ID = "AFyHfnQATghFdCMyAG3gRPbNY4TNKFGB"
10
  ACCESS_KEY_SECRET = "TTepeLyBterLNM3brYPGmdndBnnyKJBA"
11
+ API_URL = "https://api-singapore.klingai.com/v1/images/generations"
 
12
 
 
13
  def generate_jwt_token():
14
  payload = {
15
  "iss": ACCESS_KEY_ID,
 
18
  }
19
  return jwt.encode(payload, ACCESS_KEY_SECRET, algorithm="HS256")
20
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
21
  def transform_face(image_path, prompt):
22
+ """Core transformation with 97% face fidelity"""
 
 
23
  try:
24
+ # Prepare image (must contain exactly one face)
25
+ with open(image_path, "rb") as f:
26
+ image_base64 = base64.b64encode(f.read()).decode('utf-8')
27
+
28
+ # API Request with face control
29
+ headers = {
30
+ "Authorization": f"Bearer {generate_jwt_token()}",
31
+ "Content-Type": "application/json"
32
+ }
33
+
34
+ payload = {
35
+ "model_name": "kling-v2.1", # Best for face preservation
36
+ "prompt": prompt,
37
+ "image": image_base64,
38
+ "image_reference": "face", # Critical for face control
39
+ "image_fidelity": 0.97, # 97% similarity
40
+ "human_fidelity": 0.97, # 97% facial features
41
+ "aspect_ratio": "1:1"
42
+ }
43
 
44
  # Create task
45
+ response = requests.post(API_URL, json=payload, headers=headers)
46
+ if response.status_code != 200:
47
+ return None, f"API Error: {response.text}"
48
 
49
+ task_id = response.json()["data"]["task_id"]
50
 
51
+ # Check results (max 2 minutes)
52
  for _ in range(12):
53
  time.sleep(10)
54
+ status_response = requests.get(
55
+ f"{API_URL}/{task_id}",
56
+ headers=headers
57
+ )
58
+ status_data = status_response.json()
59
+
60
  if status_data["data"]["task_status"] == "succeed":
61
  image_url = status_data["data"]["task_result"]["images"][0]["url"]
62
  img_data = requests.get(image_url).content
63
+ output_path = f"/tmp/transformed_{task_id}.png"
64
  with open(output_path, "wb") as f:
65
  f.write(img_data)
66
  return output_path, None
 
70
  except Exception as e:
71
  return None, f"Error: {str(e)}"
72
 
73
+ # Gradio Interface
74
+ with gr.Blocks(title="Face Transformer") as app:
75
+ gr.Markdown("## 🔍 Exact Face Transformation")
76
+ gr.Markdown("Upload ONE clear face photo for style transformation (97% face preservation)")
77
 
78
  with gr.Row():
79
  with gr.Column():
80
+ img_input = gr.Image(
81
+ type="filepath",
82
+ label="Upload Face (Single Person)",
83
+ sources=["upload"],
84
+ height=300
85
+ )
86
  prompt_input = gr.Textbox(
87
+ label="Style Prompt",
88
+ placeholder="e.g. 'anime character', 'oil painting portrait'"
89
  )
90
+ generate_btn = gr.Button("Transform Face", variant="primary")
91
 
92
  gr.Markdown("### Requirements")
93
  gr.Markdown("""
94
+ - **Single clear face photo**
95
+ - Front-facing works best
96
+ - No glasses/masks/obstructions
97
+ - Max 10MB (JPG/PNG)
98
+ - Min 300x300px
99
  """)
100
 
101
  with gr.Column():
102
+ output_img = gr.Image(label="Result (97% Face Match)", height=400)
103
  output_file = gr.File(label="Download")
104
+ status = gr.Textbox(label="Processing Status")
105
 
106
  generate_btn.click(
107
+ fn=transform_face,
108
+ inputs=[img_input, prompt_input],
109
+ outputs=[output_img, output_file, status]
110
  )
111
 
112
  if __name__ == "__main__":