Spaces:
Runtime error
Runtime error
File size: 9,749 Bytes
34b628f a673085 34b628f 23c1749 29dc892 69b2b0d c7bdfd6 34b628f c7bdfd6 d3f1c7e 34b628f d3f1c7e 6f1d721 c7bdfd6 6f1d721 c7bdfd6 23c1749 c7bdfd6 23c1749 c7bdfd6 23c1749 c7bdfd6 6f1d721 29dc892 c7bdfd6 29dc892 c7bdfd6 29dc892 6f1d721 23c1749 29dc892 23c1749 29dc892 c7bdfd6 29dc892 23c1749 29dc892 c7bdfd6 29dc892 23c1749 29dc892 23c1749 c7bdfd6 29dc892 c7bdfd6 29dc892 c7bdfd6 29dc892 c7bdfd6 29dc892 c7bdfd6 29dc892 23c1749 71e17cd 34b628f 69b2b0d c7bdfd6 29dc892 c7bdfd6 29dc892 f6da474 6f1d721 5943c54 6f1d721 c7bdfd6 5d333e7 29dc892 23c1749 c7bdfd6 23c1749 c7bdfd6 23c1749 29dc892 c7bdfd6 bfc4b11 c7bdfd6 20b9aa1 c7bdfd6 23c1749 c7bdfd6 23c1749 c7bdfd6 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 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 | import gradio as gr
import torch
from diffusers import FluxFillPipeline
from diffusers.utils import load_image
from PIL import Image, ImageDraw
import numpy as np
import spaces
import requests
# Model setup
pipe = FluxFillPipeline.from_pretrained(
"black-forest-labs/FLUX.1-Fill-dev",
torch_dtype=torch.bfloat16
).to("cuda")
# Translation function
@spaces.GPU
def translate_albanian_to_english(text):
if not text.strip():
return ""
for attempt in range(2):
try:
response = requests.post(
"https://hal1993-mdftranslation1234567890abcdef1234567890-fc073a6.hf.space/v1/translate",
json={"from_language": "sq", "to_language": "en", "input_text": text},
headers={"accept": "application/json", "Content-Type": "application/json"},
timeout=5
)
response.raise_for_status()
translated = response.json().get("translate", "")
return translated
except Exception as e:
if attempt == 1:
raise gr.Error(f"Përkthimi dështoi: {str(e)}")
raise gr.Error("Përkthimi dështoi. Ju lutem provoni përsëri.")
# Aspect ratio function
def update_aspect_ratio(ratio):
if ratio == "1:1":
return 640, 640
elif ratio == "9:16":
width = 512
height = int(round(512 * 16 / 9 / 8)) * 8 # Round to nearest multiple of 8
return width, height
elif ratio == "16:9":
width = int(round(512 * 16 / 9 / 8)) * 8 # Round to nearest multiple of 8
height = 512
return width, height
return 640, 640 # Default to 1:1
# Core processing functions
def can_expand(source_width, source_height, target_width, target_height, alignment):
if alignment in ("Left", "Right") and source_width >= target_width:
return False
if alignment in ("Top", "Bottom") and source_height >= target_height:
return False
return True
def prepare_image_and_mask(image, width, height, overlap_percentage, resize_option, alignment):
if image is None:
raise gr.Error("Ju lutem ngarkoni një imazh.")
target_size = (width, height)
# Resize image based on scale factor
scale_factor = min(target_size[0] / image.width, target_size[1] / image.height)
new_width = int(image.width * scale_factor)
new_height = int(image.height * scale_factor)
source = image.resize((new_width, new_height), Image.LANCZOS)
# Map resize_option to percentage
resize_map = {
"E Plotë": 100,
"75%": 75,
"50%": 50,
"33%": 33,
"25%": 25
}
resize_percentage = resize_map.get(resize_option, 75) # Default to 75% if invalid
# Apply resize percentage
resize_factor = resize_percentage / 100
new_width = int(source.width * resize_factor)
new_height = int(source.height * resize_factor)
new_width = max(new_width, 64) # Ensure minimum size
new_height = max(new_height, 64)
source = source.resize((new_width, new_height), Image.LANCZOS)
# Calculate overlap in pixels
overlap_x = int(new_width * (overlap_percentage / 100))
overlap_y = int(new_height * (overlap_percentage / 100))
overlap_x = max(overlap_x, 1)
overlap_y = max(overlap_y, 1)
# Calculate margins based on alignment
if alignment == "Middle":
margin_x = (target_size[0] - new_width) // 2
margin_y = (target_size[1] - new_height) // 2
elif alignment == "Left":
margin_x = 0
margin_y = (target_size[1] - new_height) // 2
elif alignment == "Right":
margin_x = target_size[0] - new_width
margin_y = (target_size[1] - new_height) // 2
elif alignment == "Top":
margin_x = (target_size[0] - new_width) // 2
margin_y = 0
elif alignment == "Bottom":
margin_x = (target_size[0] - new_width) // 2
margin_y = target_size[1] - new_height
margin_x = max(0, min(margin_x, target_size[0] - new_width))
margin_y = max(0, min(margin_y, target_size[1] - new_height))
# Create background and paste source image
background = Image.new('RGB', target_size, (255, 255, 255))
background.paste(source, (margin_x, margin_y))
# Create mask
mask = Image.new('L', target_size, 255)
mask_draw = ImageDraw.Draw(mask)
white_gaps_patch = 2
left_overlap = margin_x + overlap_x
right_overlap = margin_x + new_width - overlap_x
top_overlap = margin_y + overlap_y
bottom_overlap = margin_y + new_height - overlap_y
if alignment == "Left":
left_overlap = margin_x
elif alignment == "Right":
right_overlap = margin_x + new_width
elif alignment == "Top":
top_overlap = margin_y
elif alignment == "Bottom":
bottom_overlap = margin_y + new_height
mask_draw.rectangle([
(left_overlap, top_overlap),
(right_overlap, bottom_overlap)
], fill=0)
return background, mask
@spaces.GPU
def inpaint(image, width, height, overlap_percentage, num_inference_steps, resize_option, prompt, progress=gr.Progress(track_tqdm=True)):
# Translate Albanian prompt to English
final_prompt = translate_albanian_to_english(prompt.strip()) if prompt.strip() else ""
# Prepare image and mask
background, mask = prepare_image_and_mask(
image, width, height, overlap_percentage, resize_option, alignment="Middle"
)
# Check if expansion is possible
if not can_expand(background.width, background.height, width, height, "Middle"):
alignment = "Middle"
# Create control image
cnet_image = background.copy()
cnet_image.paste(0, (0, 0), mask)
# Run inpainting
try:
result = pipe(
prompt=final_prompt,
height=height,
width=width,
image=cnet_image,
mask_image=mask,
num_inference_steps=num_inference_steps,
guidance_scale=50,
).images[0]
except Exception as e:
raise gr.Error(f"Gabim gjatë gjenerimit të imazhit: {str(e)}")
# Combine result with control image
result = result.convert("RGBA")
cnet_image.paste(result, (0, 0), mask)
return np.array(cnet_image) # Return as NumPy array for gr.Image
# Gradio interface
def create_demo():
with gr.Blocks() as demo:
# CSS for 320px gap, download button scaling, and container width constraint
gr.HTML("""
<style>
body::before {
content: "";
display: block;
height: 320px;
background-color: var(--body-background-fill);
}
button[aria-label="Fullscreen"], button[aria-label="Fullscreen"]:hover {
display: none !important;
visibility: hidden !important;
opacity: 0 !important;
pointer-events: none !important;
}
button[aria-label="Share"], button[aria-label="Share"]:hover {
display: none !important;
}
button[aria-label="Download"] {
transform: scale(3);
transform-origin: top right;
margin: 0 !important;
padding: 6px !important;
}
.constrained-container {
max-width: 600px; /* Limits container width */
margin: 0 auto; /* Centers the container */
}
</style>
""")
gr.Markdown("# Zgjeroni Imazhin")
gr.Markdown("Zgjeroni imazhin duke plotësuar sfondin bazuar në përshkrimin e dhënë")
with gr.Row():
with gr.Column(elem_classes="constrained-container"):
input_image = gr.Image(sources='upload', type="pil", label="Imazhi i Ngarkuar", height=480, width=480)
prompt = gr.Textbox(label="Përshkrimi", placeholder="Shkruani përshkrimin këtu (opsionale)")
aspect_ratio = gr.Radio(choices=["9:16", "1:1", "16:9"], value="1:1", label="Raporti i Aspektit")
resize_option = gr.Radio(
choices=["E Plotë", "75%", "50%", "33%", "25%"],
value="75%",
label="Madhësia e Imazhit të Hyrjes",
info="Zgjidhni sa i madh të jetë imazhi i hyrjes në kanavacën përfundimtare"
)
generate_button = gr.Button(value="Gjenero")
result_image = gr.Image(label="Rezultati", type="numpy", height=480, width=480, elem_classes="constrained-container")
# Hidden components for processing
width_slider = gr.Slider(label="Gjerësia e Synuar", minimum=256, maximum=1536, value=640, step=8, visible=False)
height_slider = gr.Slider(label="Lartësia e Synuar", minimum=256, maximum=1536, value=640, step=8, visible=False)
overlap_percentage = gr.Slider(label="Përqindja e Mbivendosjes", minimum=1, maximum=50, value=10, step=1, visible=False)
num_inference_steps = gr.Slider(label="Hapat", minimum=2, maximum=50, value=28, step=1, visible=False)
# Update hidden sliders based on aspect ratio
aspect_ratio.change(
fn=update_aspect_ratio,
inputs=[aspect_ratio],
outputs=[width_slider, height_slider]
)
# Bind the generate button
inputs = [
input_image, width_slider, height_slider, overlap_percentage, num_inference_steps,
resize_option, prompt
]
generate_button.click(
fn=inpaint,
inputs=inputs,
outputs=[result_image]
)
return demo
if __name__ == "__main__":
print(f"Gradio version: {gr.__version__}")
app = create_demo()
app.queue(max_size=12).launch(server_name='0.0.0.0') |