Munaf1987 commited on
Commit
e81c596
·
verified ·
1 Parent(s): 1ca3ab1

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +58 -43
app.py CHANGED
@@ -1,62 +1,77 @@
1
- # app.py
2
  import gradio as gr
3
- import torch, io, base64
4
- from PIL import Image
5
  from diffusers import StableDiffusionImg2ImgPipeline
6
- from vtoonify_model import load_vtoonify # see below
 
 
 
7
  import spaces
8
 
9
- # Load models
10
  pipe_ghibli = StableDiffusionImg2ImgPipeline.from_pretrained(
11
  "nitrosocke/Ghibli-Diffusion", torch_dtype=torch.float16
12
- ).to("cuda") # Ghibli-style fine-tuned SD :contentReference[oaicite:1]{index=1}
13
 
14
- pipe_vtoonify = load_vtoonify().to("cuda") # cartoonization model loader
 
15
 
16
- # Helpers for base64 conversion
17
- def pil_to_b64(img: Image.Image) -> str:
18
- buf = io.BytesIO()
19
- img.save(buf, format="PNG")
20
- return base64.b64encode(buf.getvalue()).decode()
21
 
22
- def b64_to_pil(b64: str) -> Image.Image:
23
- data = base64.b64decode(b64)
24
- return Image.open(io.BytesIO(data)).convert("RGB")
25
 
26
- # Core processor
27
- def run_effect(input_b64: str, effect: str) -> dict:
28
- img = b64_to_pil(input_b64)
 
 
 
 
 
 
 
 
 
 
 
29
  if effect == "ghibli":
30
- out = pipe_ghibli(prompt="ghibli style", image=img, strength=0.5, guidance_scale=7.5).images[0]
31
  else:
32
- out = pipe_vtoonify(img)
33
- return {"output_b64": pil_to_b64(out)}
34
-
35
- @gr.utils.decorators.thread_safe()
36
- @spaces.GPU # enables GPU on ZeroGPU Infra
37
- def api_process(input_b64, effect):
38
- return run_effect(input_b64, effect)
39
 
40
- def gradio_process(img: Image.Image, effect: str) -> Image.Image:
41
- # Reuse logic, bypass base64
42
- in_b64 = pil_to_b64(img)
43
- return b64_to_pil(run_effect(in_b64, effect)["output_b64"])
 
44
 
 
45
  with gr.Blocks() as demo:
46
- gr.Markdown("# Ghibli & VToonify Effects 🎨")
47
 
48
  with gr.Tab("Web UI"):
49
- inp = gr.Image(type="pil", label="Upload Image")
50
- eff = gr.Radio(["ghibli", "vtoonify"], label="Effect")
51
- btn = gr.Button("Apply Effect")
52
- out = gr.Image(label="Result")
53
- btn.click(gradio_process, [inp, eff], out)
54
-
55
- with gr.Tab("API (base64)"):
56
- inp_b64 = gr.Textbox(lines=4, label="Input Image (base64)")
57
- eff2 = gr.Radio(["ghibli", "vtoonify"], label="Effect")
58
- btn2 = gr.Button("Run API")
59
- out_b64 = gr.Textbox(lines=4, label="Output Image (base64)")
60
- btn2.click(api_process, [inp_b64, eff2], out_b64)
 
 
 
 
 
61
 
62
  demo.launch()
 
 
1
  import gradio as gr
2
+ import torch
 
3
  from diffusers import StableDiffusionImg2ImgPipeline
4
+ from torchvision import transforms
5
+ from PIL import Image
6
+ import io
7
+ import base64
8
  import spaces
9
 
10
+ # Load Ghibli model
11
  pipe_ghibli = StableDiffusionImg2ImgPipeline.from_pretrained(
12
  "nitrosocke/Ghibli-Diffusion", torch_dtype=torch.float16
13
+ ).to("cuda")
14
 
15
+ # Load CartoonGAN model
16
+ cartoon_model = torch.hub.load('AK391/CartoonGAN', 'cartoon_gan', pretrained=True).to("cuda").eval()
17
 
18
+ # Base64 utilities
19
+ def pil_to_base64(img: Image.Image) -> str:
20
+ buffer = io.BytesIO()
21
+ img.save(buffer, format="PNG")
22
+ return base64.b64encode(buffer.getvalue()).decode()
23
 
24
+ def base64_to_pil(b64: str) -> Image.Image:
25
+ image_data = base64.b64decode(b64)
26
+ return Image.open(io.BytesIO(image_data)).convert("RGB")
27
 
28
+ # CartoonGAN processor
29
+ def apply_cartoon_gan(img: Image.Image) -> Image.Image:
30
+ transform = transforms.Compose([
31
+ transforms.Resize((256, 256)),
32
+ transforms.ToTensor()
33
+ ])
34
+ img_tensor = transform(img).unsqueeze(0).to("cuda")
35
+ with torch.no_grad():
36
+ output = cartoon_model(img_tensor)[0].clamp(0, 1).cpu()
37
+ output_pil = transforms.ToPILImage()(output)
38
+ return output_pil
39
+
40
+ # Unified effect processor
41
+ def process_image(input_image: Image.Image, effect: str) -> Image.Image:
42
  if effect == "ghibli":
43
+ output_image = pipe_ghibli(prompt="ghibli style", image=input_image, strength=0.5, guidance_scale=7.5).images[0]
44
  else:
45
+ output_image = apply_cartoon_gan(input_image)
46
+ return output_image
 
 
 
 
 
47
 
48
+ @spaces.GPU
49
+ def process_base64(input_b64: str, effect: str) -> str:
50
+ input_image = base64_to_pil(input_b64)
51
+ output_image = process_image(input_image, effect)
52
+ return pil_to_base64(output_image)
53
 
54
+ # Gradio UI
55
  with gr.Blocks() as demo:
56
+ gr.Markdown("# 🎨 Ghibli & CartoonGAN Effects")
57
 
58
  with gr.Tab("Web UI"):
59
+ with gr.Row():
60
+ image_input = gr.Image(type="pil", label="Upload Image")
61
+ effect_selector = gr.Radio(["ghibli", "cartoon"], label="Select Effect")
62
+ with gr.Row():
63
+ apply_button = gr.Button("Apply Effect")
64
+ with gr.Row():
65
+ image_output = gr.Image(label="Processed Image")
66
+
67
+ apply_button.click(process_image, [image_input, effect_selector], image_output)
68
+
69
+ with gr.Tab("Base64 API"):
70
+ base64_input = gr.Textbox(label="Input Image (Base64)", lines=5)
71
+ effect_choice = gr.Radio(["ghibli", "cartoon"], label="Select Effect")
72
+ api_button = gr.Button("Run API")
73
+ base64_output = gr.Textbox(label="Output Image (Base64)", lines=5)
74
+
75
+ api_button.click(process_base64, [base64_input, effect_choice], base64_output)
76
 
77
  demo.launch()