Chingkheinganba commited on
Commit
c941df2
Β·
verified Β·
1 Parent(s): 364f40f

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +54 -56
app.py CHANGED
@@ -4,93 +4,90 @@ import gradio as gr
4
  from PIL import Image, ImageDraw, ImageFont
5
  from huggingface_hub import InferenceClient
6
 
7
- # =============== Config ===============
8
- HF_TOKEN = os.getenv("HF_TOKEN") # set this in your environment
9
- MODEL_ID = "timbrooks/instruct-pix2pix"
 
 
 
 
 
10
 
11
  STYLES = [
12
- "Modern Minimalist",
13
- "Victorian",
14
- "Brutalist",
15
- "Mediterranean",
16
- "Gothic Cathedral",
17
- "Japanese Zen",
18
- "Art Deco",
19
- "Futuristic",
20
- "Scandinavian",
21
- "Meditation Retreat"
22
  ]
23
 
24
- # =============== Helpers ===============
25
  def info_image(msg: str, w: int = 768, h: int = 512) -> Image.Image:
26
- """Simple image with centered text (used for errors)."""
27
  img = Image.new("RGB", (w, h), "#2C3E50")
28
  d = ImageDraw.Draw(img)
29
  font = ImageFont.load_default()
30
- lines = []
31
- words = msg.split()
32
- line = ""
33
- for word in words:
34
  test = (line + " " + word).strip()
35
  if d.textlength(test, font=font) < (w - 40):
36
  line = test
37
  else:
38
- lines.append(line)
39
- line = word
40
- if line:
41
- lines.append(line)
42
- total_h = len(lines) * 18
43
- y = (h - total_h) // 2
44
  for L in lines:
45
  tw = d.textlength(L, font=font)
46
  d.text(((w - tw) // 2, y), L, fill="white", font=font)
47
  y += 18
48
  return img
49
 
 
 
 
 
 
 
 
50
 
51
  def build_prompt(style: str) -> str:
52
  return (
53
  f"Transform this house into a {style} architectural style. "
54
- f"Keep the same perspective and composition. Photorealistic, high detail, realistic lighting."
 
55
  )
56
 
57
- # =============== Core ===============
58
  def transform_house(input_image: Image.Image, style: str):
59
- """Upload a house image + style -> transformed image from HF model."""
60
  if input_image is None:
61
- return info_image("Please upload a house photo first.")
62
-
63
  if not HF_TOKEN:
64
- return info_image("HF_TOKEN is missing. Set it in your environment before running.")
65
 
66
- try:
67
- client = InferenceClient(model=MODEL_ID, token=HF_TOKEN)
68
- prompt = build_prompt(style)
 
69
 
70
- # InferenceClient.image_to_image returns bytes in most versions; handle either bytes or PIL.Image
71
- result = client.image_to_image(
72
- prompt=prompt,
73
- image=input_image,
74
- negative_prompt="blurry, low quality, distorted, text, watermark, extra buildings",
75
- guidance_scale=7.0,
76
- image_guidance_scale=1.5,
77
- num_inference_steps=30,
78
- )
 
 
 
 
 
 
 
79
 
80
- if isinstance(result, bytes):
81
- return Image.open(io.BytesIO(result)).convert("RGB")
82
- elif isinstance(result, Image.Image):
83
- return result.convert("RGB")
84
- else:
85
- return info_image("Unexpected response from the model.")
86
- except Exception as e:
87
- # Graceful error panel instead of crashing the app
88
- return info_image(f"Generation failed: {e}")
89
 
90
- # =============== UI ===============
91
  with gr.Blocks() as demo:
92
  gr.Markdown("# 🏠 House β†’ Style Remix (Hugging Face)")
93
-
94
  with gr.Row():
95
  with gr.Column():
96
  inp = gr.Image(type="pil", label="Upload a house photo")
@@ -98,9 +95,10 @@ with gr.Blocks() as demo:
98
  btn = gr.Button("Generate", variant="primary")
99
  with gr.Column():
100
  out = gr.Image(label="Transformed House", height=480)
 
101
 
102
- btn.click(fn=transform_house, inputs=[inp, style], outputs=out)
103
 
104
  if __name__ == "__main__":
105
- # Run: HF_TOKEN=your_token python app.py
106
  demo.launch(debug=False)
 
4
  from PIL import Image, ImageDraw, ImageFont
5
  from huggingface_hub import InferenceClient
6
 
7
+ # Read your HF token from env
8
+ HF_TOKEN = os.getenv("HF_TOKEN")
9
+
10
+ # A couple of reasonable models for image-to-image editing on HF Serverless
11
+ MODEL_CANDIDATES = [
12
+ "timbrooks/instruct-pix2pix", # instruction-based edits
13
+ "stabilityai/stable-diffusion-2-1" # img2img capable baseline
14
+ ]
15
 
16
  STYLES = [
17
+ "Modern Minimalist", "Victorian", "Brutalist", "Mediterranean",
18
+ "Gothic Cathedral", "Japanese Zen", "Art Deco", "Futuristic",
19
+ "Scandinavian", "Meditation Retreat"
 
 
 
 
 
 
 
20
  ]
21
 
 
22
  def info_image(msg: str, w: int = 768, h: int = 512) -> Image.Image:
23
+ """Simple dark-blue panel with centered text (for graceful errors)."""
24
  img = Image.new("RGB", (w, h), "#2C3E50")
25
  d = ImageDraw.Draw(img)
26
  font = ImageFont.load_default()
27
+ lines, line = [], ""
28
+ for word in msg.split():
 
 
29
  test = (line + " " + word).strip()
30
  if d.textlength(test, font=font) < (w - 40):
31
  line = test
32
  else:
33
+ lines.append(line); line = word
34
+ if line: lines.append(line)
35
+ y = (h - 18 * len(lines)) // 2
 
 
 
36
  for L in lines:
37
  tw = d.textlength(L, font=font)
38
  d.text(((w - tw) // 2, y), L, fill="white", font=font)
39
  y += 18
40
  return img
41
 
42
+ def pil_to_png_bytes(img: Image.Image) -> bytes:
43
+ """Convert a PIL image to PNG bytes for HF InferenceClient."""
44
+ if img.mode not in ("RGB", "L"):
45
+ img = img.convert("RGB")
46
+ buf = io.BytesIO()
47
+ img.save(buf, format="PNG")
48
+ return buf.getvalue()
49
 
50
  def build_prompt(style: str) -> str:
51
  return (
52
  f"Transform this house into a {style} architectural style. "
53
+ f"Keep the same layout, perspective, and composition. "
54
+ f"Photorealistic, high detail, realistic lighting."
55
  )
56
 
 
57
  def transform_house(input_image: Image.Image, style: str):
58
+ """Upload a house + style -> transformed image from HF model, with status text."""
59
  if input_image is None:
60
+ return info_image("Please upload a house photo first."), "Please upload a house photo first."
 
61
  if not HF_TOKEN:
62
+ return info_image("Missing HF_TOKEN"), "❌ Missing HF_TOKEN (set env var HF_TOKEN)."
63
 
64
+ img_bytes = pil_to_png_bytes(input_image)
65
+ client = InferenceClient(token=HF_TOKEN)
66
+ prompt = build_prompt(style)
67
+ last_err = None
68
 
69
+ for model_id in MODEL_CANDIDATES:
70
+ try:
71
+ # Important: pass bytes, not a PIL image
72
+ out_img = client.image_to_image(
73
+ image=img_bytes,
74
+ prompt=prompt,
75
+ negative_prompt="blurry, low quality, distorted, text, watermark, extra buildings",
76
+ guidance_scale=7.0,
77
+ num_inference_steps=30,
78
+ # image_guidance_scale is not universally supported by the serverless backend,
79
+ # so we avoid it for maximum compatibility.
80
+ model=model_id
81
+ )
82
+ return out_img.convert("RGB"), f"βœ… Success with {model_id}"
83
+ except Exception as e:
84
+ last_err = str(e)
85
 
86
+ return info_image("Generation failed. See status."), f"❌ Generation failed. Last error: {last_err}"
 
 
 
 
 
 
 
 
87
 
88
+ # -------- UI --------
89
  with gr.Blocks() as demo:
90
  gr.Markdown("# 🏠 House β†’ Style Remix (Hugging Face)")
 
91
  with gr.Row():
92
  with gr.Column():
93
  inp = gr.Image(type="pil", label="Upload a house photo")
 
95
  btn = gr.Button("Generate", variant="primary")
96
  with gr.Column():
97
  out = gr.Image(label="Transformed House", height=480)
98
+ status = gr.Textbox(label="Status", interactive=False)
99
 
100
+ btn.click(transform_house, inputs=[inp, style], outputs=[out, status])
101
 
102
  if __name__ == "__main__":
103
+ # Run: HF_TOKEN=hf_xxx python app.py
104
  demo.launch(debug=False)