Spaces:
Sleeping
Sleeping
Upload folder using huggingface_hub
Browse files- .gitignore +13 -0
- README.md +3 -9
- index.py +167 -0
- requirements.txt +3 -0
.gitignore
ADDED
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.vercel
|
2 |
+
*.log
|
3 |
+
*.pyc
|
4 |
+
__pycache__
|
5 |
+
|
6 |
+
# Environments
|
7 |
+
.env
|
8 |
+
.venv
|
9 |
+
env/
|
10 |
+
venv/
|
11 |
+
ENV/
|
12 |
+
env.bak/
|
13 |
+
venv.bak/
|
README.md
CHANGED
@@ -1,12 +1,6 @@
|
|
1 |
---
|
2 |
-
title:
|
3 |
-
|
4 |
-
colorFrom: purple
|
5 |
-
colorTo: purple
|
6 |
sdk: gradio
|
7 |
-
sdk_version: 4.
|
8 |
-
app_file: app.py
|
9 |
-
pinned: false
|
10 |
---
|
11 |
-
|
12 |
-
Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
|
|
|
1 |
---
|
2 |
+
title: generate_renders
|
3 |
+
app_file: index.py
|
|
|
|
|
4 |
sdk: gradio
|
5 |
+
sdk_version: 4.36.1
|
|
|
|
|
6 |
---
|
|
|
|
index.py
ADDED
@@ -0,0 +1,167 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import base64
|
3 |
+
import numpy as np
|
4 |
+
from PIL import Image
|
5 |
+
import io
|
6 |
+
import requests
|
7 |
+
|
8 |
+
import replicate
|
9 |
+
from flask import Flask, request
|
10 |
+
import gradio as gr
|
11 |
+
|
12 |
+
import openai
|
13 |
+
from openai import OpenAI
|
14 |
+
|
15 |
+
from dotenv import load_dotenv, find_dotenv
|
16 |
+
|
17 |
+
import json
|
18 |
+
|
19 |
+
# Locate the .env file
|
20 |
+
dotenv_path = find_dotenv()
|
21 |
+
|
22 |
+
load_dotenv(dotenv_path)
|
23 |
+
|
24 |
+
OPENAI_API_KEY = os.getenv('OPENAI_API_KEY')
|
25 |
+
REPLICATE_API_TOKEN = os.getenv('REPLICATE_API_TOKEN')
|
26 |
+
|
27 |
+
client = OpenAI()
|
28 |
+
|
29 |
+
def main(img):
|
30 |
+
mask = img['layers'][0]
|
31 |
+
|
32 |
+
base_image = Image.fromarray(img['background'].astype('uint8'))
|
33 |
+
img_base_64 = img_to_base64(base_image)
|
34 |
+
|
35 |
+
if is_transparent(mask) == True:
|
36 |
+
mask_base_64 = None
|
37 |
+
else:
|
38 |
+
mask_img = create_mask_image(mask)
|
39 |
+
mask_base_64 = img_to_base64(mask_img)
|
40 |
+
|
41 |
+
prompt = call_openai(img_base_64)
|
42 |
+
|
43 |
+
output_urls = generate_image(prompt, img_base_64, mask_base_64)
|
44 |
+
|
45 |
+
output_images = [download_image(url) for url in output_urls[3:]] # Start from the 4th image
|
46 |
+
|
47 |
+
return output_images
|
48 |
+
|
49 |
+
def generate_image(prompt, img, mask):
|
50 |
+
input_data = {
|
51 |
+
"image": img,
|
52 |
+
"prompt": "highly realistic photograpy " + prompt + ", expensive",
|
53 |
+
"refine": "no_refiner",
|
54 |
+
"scheduler": "K_EULER",
|
55 |
+
"lora_scale": 0.8,
|
56 |
+
"num_outputs": 4,
|
57 |
+
"controlnet_1": "edge_canny",
|
58 |
+
"controlnet_2": "depth_midas",
|
59 |
+
"controlnet_3": "lineart",
|
60 |
+
"guidance_scale": 7.5,
|
61 |
+
"apply_watermark": False,
|
62 |
+
"negative_prompt":"worst quality, low quality, illustration, 2d, painting, cartoons, sketch",
|
63 |
+
"prompt_strength": 0.75,
|
64 |
+
"sizing_strategy": "controlnet_1_image",
|
65 |
+
"controlnet_1_end": 1,
|
66 |
+
"controlnet_2_end": 1,
|
67 |
+
"controlnet_3_end": 1,
|
68 |
+
"controlnet_1_image": img,
|
69 |
+
"controlnet_1_start": 0,
|
70 |
+
"controlnet_2_image": img,
|
71 |
+
"controlnet_2_start": 0,
|
72 |
+
"controlnet_3_image": img,
|
73 |
+
"controlnet_3_start": 0,
|
74 |
+
"num_inference_steps": 30,
|
75 |
+
"controlnet_1_conditioning_scale": 0.8,
|
76 |
+
"controlnet_2_conditioning_scale": 0.8,
|
77 |
+
"controlnet_3_conditioning_scale": 0.75
|
78 |
+
}
|
79 |
+
|
80 |
+
if mask is not None:
|
81 |
+
input_data["mask"] = mask
|
82 |
+
else:
|
83 |
+
input_data["prompt_strength"] = .6
|
84 |
+
|
85 |
+
output = replicate.run(
|
86 |
+
"fofr/realvisxl-v3-multi-controlnet-lora:90a4a3604cd637cb9f1a2bdae1cfa9ed869362ca028814cdce310a78e27daade",
|
87 |
+
input=input_data
|
88 |
+
)
|
89 |
+
|
90 |
+
return output
|
91 |
+
|
92 |
+
def download_image(url):
|
93 |
+
response = requests.get(url)
|
94 |
+
img = Image.open(io.BytesIO(response.content))
|
95 |
+
return img
|
96 |
+
|
97 |
+
def create_mask_image(mask_array):
|
98 |
+
# Convert the mask to a numpy array if it's not already
|
99 |
+
if not isinstance(mask_array, np.ndarray):
|
100 |
+
mask_array = np.array(mask_array)
|
101 |
+
|
102 |
+
# Create a new array with the same shape as the mask, but only for RGB channels
|
103 |
+
processed_mask = np.zeros((mask_array.shape[0], mask_array.shape[1], 3), dtype=np.uint8)
|
104 |
+
|
105 |
+
# Set transparent parts (alpha=0) to black (0, 0, 0)
|
106 |
+
transparent_mask = mask_array[:, :, 3] == 0
|
107 |
+
processed_mask[transparent_mask] = [0, 0, 0]
|
108 |
+
|
109 |
+
# Set black parts (RGB=0, 0, 0 and alpha=255) to white (255, 255, 255)
|
110 |
+
black_mask = (mask_array[:, :, :3] == [0, 0, 0]).all(axis=2) & (mask_array[:, :, 3] == 255)
|
111 |
+
processed_mask[black_mask] = [255, 255, 255]
|
112 |
+
|
113 |
+
return Image.fromarray(processed_mask)
|
114 |
+
|
115 |
+
def is_transparent(mask_array):
|
116 |
+
return np.all(mask_array[:, :, 3] == 0)
|
117 |
+
|
118 |
+
def img_to_base64(img):
|
119 |
+
# Extract the format of the image (e.g., JPEG, PNG)
|
120 |
+
img_format = img.format if img.format else "PNG"
|
121 |
+
|
122 |
+
# Convert the image to bytes
|
123 |
+
buffered = io.BytesIO()
|
124 |
+
img.save(buffered, format=img_format)
|
125 |
+
img_base_64 = base64.b64encode(buffered.getvalue()).decode('utf-8')
|
126 |
+
return f"data:image/{img_format.lower()};base64," + img_base_64
|
127 |
+
|
128 |
+
def call_openai(image_data):
|
129 |
+
try:
|
130 |
+
response = client.chat.completions.create(
|
131 |
+
model="gpt-4o",
|
132 |
+
messages=[
|
133 |
+
{
|
134 |
+
"role": "user",
|
135 |
+
"content": [
|
136 |
+
{"type": "text", "text": "Please describe this image in one sentence, with a focus on the material and specific color (like pantone level specificity) and details of the main object in the scene. Mention the type of lighting as well."},
|
137 |
+
{
|
138 |
+
"type": "image_url",
|
139 |
+
"image_url": {
|
140 |
+
"url": image_data,
|
141 |
+
},
|
142 |
+
},
|
143 |
+
],
|
144 |
+
}
|
145 |
+
],
|
146 |
+
max_tokens=300,
|
147 |
+
)
|
148 |
+
return response.choices[0].message.content
|
149 |
+
except openai.BadRequestError as e:
|
150 |
+
print(e)
|
151 |
+
print("e type")
|
152 |
+
print(type(e))
|
153 |
+
raise gr.Error(f"You uploaded an unsupported image. Please make sure your image is below 20 MB in size and is of one the following formats: ['png', 'jpeg', 'gif', 'webp']")
|
154 |
+
except Exception as e:
|
155 |
+
raise gr.Error("Unknown Error")
|
156 |
+
|
157 |
+
# Define the brush with only black color
|
158 |
+
black_brush = gr.Brush(colors=["#000000"], default_color="#000000", color_mode="fixed")
|
159 |
+
|
160 |
+
# Using the ImageEditor component to enable drawing on the image with limited colors
|
161 |
+
demo = gr.Interface(
|
162 |
+
fn=main,
|
163 |
+
inputs=gr.ImageEditor(brush=black_brush),
|
164 |
+
outputs=[gr.Image(type="pil"), gr.Image(type="pil"), gr.Image(type="pil"), gr.Image(type="pil")]
|
165 |
+
)
|
166 |
+
|
167 |
+
demo.launch(share=False)
|
requirements.txt
ADDED
@@ -0,0 +1,3 @@
|
|
|
|
|
|
|
|
|
1 |
+
replicate
|
2 |
+
gradio
|
3 |
+
openai
|