logo-in-context / app.py
multimodalart's picture
Update app.py
85875c3 verified
raw
history blame
4.16 kB
import gradio as gr
import torch
import spaces
from diffusers import FluxInpaintPipeline
from PIL import Image, ImageFile
import numpy as np
#ImageFile.LOAD_TRUNCATED_IMAGES = True
# Initialize the pipeline
pipe = FluxInpaintPipeline.from_pretrained(
"black-forest-labs/FLUX.1-dev",
torch_dtype=torch.bfloat16
)
pipe.to("cuda")
pipe.load_lora_weights(
"ali-vilab/In-Context-LoRA",
weight_name="visual-identity-design.safetensors"
)
def square_center_crop_numpy(img, target_size=768):
if img.mode in ('RGBA', 'P'):
img = img.convert('RGB')
# Convert PIL image to numpy array
img_array = np.array(img)
# Get dimensions
height, width = img_array.shape[:2]
crop_size = min(width, height)
# Calculate crop coordinates
left = (width - crop_size) // 2
top = (height - crop_size) // 2
# Perform the crop on numpy array
img_cropped = img_array[top:top+crop_size, left:left+crop_size]
# Convert back to PIL and resize
img_pil = Image.fromarray(img_cropped)
return img_pil.resize((target_size, target_size), Image.Resampling.LANCZOS)
def duplicate_horizontally(img):
# Convert PIL Image to numpy array
width, height = img.size
if width != height:
raise ValueError(f"Input image must be square, got {width}x{height}")
img_array = np.array(img)
duplicated = np.concatenate([img_array, img_array], axis=1)
return Image.fromarray(duplicated)
# Load the mask image
mask = Image.open("mask_square.png")
def crop_input(image):
cropped_image = square_center_crop(image)
return cropped_image
@spaces.GPU
def generate(image, prompt_user, progress=gr.Progress(track_tqdm=True)):
prompt_structure = "The two-panel image showcases the logo of a brand, [LEFT] the left panel is showing the logo [RIGHT] the right panel has this logo applied to "
prompt = prompt_structure + prompt_user
print(image)
image = duplicate_horizontally(image)
out = pipe(
prompt=prompt,
image=image,
mask_image=mask,
guidance_scale=3.75,
height=768,
width=1536,
num_inference_steps=28,
max_sequence_length=256,
strength=1
).images[0]
width, height = out.size
half_width = width // 2
image_2 = out.crop((half_width, 0, width, height))
return image_2, out
with gr.Blocks() as demo:
gr.Markdown("# Logo in Context")
gr.Markdown("### In-Context LoRA + Image-to-Image, apply your logo to anything")
with gr.Row():
with gr.Column():
input_image = gr.Image(
label="Upload Logo Image",
type="pil"
)
cropped_image = gr.Image(
visible=False,
type="pil"
)
prompt_input = gr.Textbox(
label="Where should the logo be applied?",
placeholder="e.g., a coffee cup on a wooden table"
)
generate_btn = gr.Button("Generate Application", variant="primary")
with gr.Column():
output_image = gr.Image(label="Generated Application")
output_side = gr.Image(label="Side by side")
gr.Examples(
examples=[
["huggingface.png", "A hat"],
["awesome.png", "A tattoo on a leg"],
["dvd_logo.png", "a flower pot"]
],
inputs=[input_image, prompt_input],
outputs=[output_image, output_side],
fn=generate,
cache_examples="lazy"
)
with gr.Row():
gr.Markdown("""
### Instructions:
1. Upload a logo image (preferably square)
2. Describe where you'd like to see the logo applied
3. Click 'Generate Application' and wait for the result
Note: The generation process might take a few moments.
""")
# Set up the click event
generate_btn.click(
fn=crop_input,
inputs=[input_image],
outputs=[cropped_image]
).then(
fn=generate,
inputs=[cropped_image, prompt_input],
outputs=[output_image, output_side]
)
demo.launch()