Akjava commited on
Commit
6453bed
1 Parent(s): 30e18e6
Files changed (5) hide show
  1. .gitignore +6 -0
  2. app.py +116 -0
  3. demo_header.html +13 -0
  4. flux1_img2img.py +31 -0
  5. requirements.txt +7 -0
.gitignore ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ __pycache__
2
+ *.egg-info
3
+ .ipynb_checkpoints
4
+ dist
5
+ .gradio
6
+ build
app.py ADDED
@@ -0,0 +1,116 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import spaces
2
+ import gradio as gr
3
+ import re
4
+ from PIL import Image
5
+ import flux1_img2img
6
+ import os
7
+ import numpy as np
8
+ import shutil
9
+ #shutil.rmtree("/home/user/app/.gradio/cached_examples/23")
10
+
11
+ def sanitize_prompt(prompt):
12
+ # Allow only alphanumeric characters, spaces, and basic punctuation
13
+ allowed_chars = re.compile(r"[^a-zA-Z0-9\s.,!?-]")
14
+ sanitized_prompt = allowed_chars.sub("", prompt)
15
+ return sanitized_prompt
16
+
17
+ @spaces.GPU(duration=180)
18
+ def process_images(image, image2=None,prompt="a girl",inpaint_model="black-forest-labs/FLUX.1-schnell",strength=0.75,seed=0):
19
+ # I'm not sure when this happen
20
+ if not isinstance(image, dict):
21
+ if image2 == None:
22
+ print("empty mask")
23
+ return image
24
+ else:
25
+ image = dict({'background': image, 'layers': [image2]})
26
+
27
+ if image2!=None:
28
+ #print("use image2")
29
+ mask = image2
30
+ else:
31
+ if len(image['layers']) == 0:
32
+ print("empty mask")
33
+ return image
34
+ print("use layer")
35
+ mask = image['layers'][0]
36
+
37
+
38
+ output = flux1_inpaint.process_image(image["background"],mask,prompt,inpaint_model,strength,seed)
39
+
40
+ return output
41
+
42
+
43
+ def read_file(path: str) -> str:
44
+ with open(path, 'r', encoding='utf-8') as f:
45
+ content = f.read()
46
+
47
+ return content
48
+
49
+ def example_out(image,image_mask,prompt,strength,example_id):
50
+ # input
51
+ #parent,file=os.path.split(image_mask) # image is complex dict
52
+ #base,ext = os.path.splitext(file)
53
+ #key = base.split("_")[0]
54
+ return f"images/{example_id}.jpg"
55
+ #loaded_image = Image.open(f"images/{example_id}.jpg")
56
+ #return loaded_image
57
+ #return np.array(loaded_image)
58
+
59
+ css="""
60
+ #col-left {
61
+ margin: 0 auto;
62
+ max-width: 640px;
63
+ }
64
+ #col-right {
65
+ margin: 0 auto;
66
+ max-width: 640px;
67
+ }
68
+ """
69
+ demo_blocks = gr.Blocks(css=css, elem_id="demo-container")
70
+ with demo_blocks as demo:
71
+ with gr.Column():
72
+ gr.HTML(read_file("demo_header.html"))
73
+ with gr.Row():
74
+ with gr.Column():
75
+ image = gr.ImageEditor(height=800,sources=['upload','clipboard'],transforms=[],image_mode='RGB', layers=False, elem_id="image_upload", type="pil", label="Upload",brush=gr.Brush(colors=["#fff"], color_mode="fixed"))
76
+ with gr.Row(elem_id="prompt-container", equal_height=False):
77
+ with gr.Row():
78
+ prompt = gr.Textbox(label="Prompt",value="a eyes closed girl,shut eyes",placeholder="Your prompt (what you want in place of what is erased)", elem_id="prompt")
79
+
80
+ btn = gr.Button("Inpaint", elem_id="run_button",variant="primary")
81
+
82
+ image_mask = gr.Image(sources=['upload','clipboard'], elem_id="mask_upload", type="pil", label="Mask_Upload",height=400, value=None)
83
+ with gr.Accordion(label="Advanced Settings", open=False):
84
+ with gr.Row( equal_height=True):
85
+ strength = gr.Number(value=0.75, minimum=0, maximum=1.0, step=0.01, label="Inpaint strength")
86
+ seed = gr.Number(value=0, minimum=0, step=1, label="Inpaint seed")
87
+ models = ["black-forest-labs/FLUX.1-schnell"]
88
+ inpaint_model = gr.Dropdown(label="modes", choices=models, value="black-forest-labs/FLUX.1-schnell")
89
+ id_input=gr.Text(label="Name", visible=False)
90
+
91
+ with gr.Column():
92
+ image_out = gr.Image(height=800,sources=[],label="Output", elem_id="output-img",format="jpg")
93
+
94
+
95
+
96
+
97
+ btn.click(fn=process_images, inputs=[image, image_mask,prompt,inpaint_model,strength,seed], outputs =image_out, api_name='infer')
98
+ gr.Examples(
99
+ examples=[
100
+ #["images/00547245_99.jpg", "images/00547245_99_mask.jpg","a beautiful girl,eyes closed",0.8,"images/00547245.jpg"],
101
+ #["images/00538245_paint.jpg", "images/00538245_mask.jpg","a beautiful girl,wearing t-shirt",0.7,"images/00538245.jpg"],
102
+ #["images/00207245_18.jpg", "images/00207245_18_mask.jpg","a beautiful girl,mouth opened",0.2,"images/00207245.jpg"]
103
+ ]
104
+ ,
105
+ #fn=example_out,
106
+ inputs=[image,image_mask,prompt,strength,image_out],
107
+ #outputs=[test_out],
108
+ #cache_examples=False,
109
+ )
110
+ gr.HTML(
111
+ """
112
+
113
+ """
114
+ )
115
+
116
+ demo_blocks.queue(max_size=25).launch(share=False,debug=True)
demo_header.html ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div style="text-align: center;">
2
+ <h1>
3
+ Flux.1-schnell mask-inpaint
4
+ </h1>
5
+ <p>Making face images for <a href="https://huggingface.co/spaces/Akjava/godot-huggingface-chain">AI Diagram Chat with Voice/Face Character</a></p>
6
+ <p>
7
+
8
+ See examples.
9
+ The image requires guide painting.(To generate an image with closed eyes, fill the eye area with skin color.)
10
+ You can draw mask or upload mask.BE CAREFUL UPLOAEDED MASK(If the uploaded mask exist,ignore your painted mask)
11
+ </p>
12
+ <p>Hint:step by step,reduce strength.blur guide-paint and mask</p>
13
+ </div>
flux1_img2img.py ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import torch
2
+ from diffusers import FluxInpaintPipeline
3
+
4
+ from PIL import Image
5
+ import sys
6
+ import spaces
7
+
8
+ # I only test with FLUX.1-schnell
9
+
10
+ @spaces.GPU
11
+ def process_image(image,mask_image,prompt="a person",model_id="black-forest-labs/FLUX.1-schnell",strength=0.75,seed=0,num_inference_steps=4):
12
+ if image == None:
13
+ return None
14
+
15
+ pipe = FluxInpaintPipeline.from_pretrained(model_id, torch_dtype=torch.bfloat16)
16
+ pipe.to("cuda")
17
+
18
+ generators = []
19
+ generator = torch.Generator("cuda").manual_seed(seed)
20
+ generators.append(generator)
21
+ # more parameter see https://huggingface.co/docs/diffusers/api/pipelines/flux#diffusers.FluxInpaintPipeline
22
+ output = pipe(prompt=prompt, image=image, mask_image=mask_image,generator=generator,strength=strength)
23
+
24
+ return output.images[0]
25
+
26
+ if __name__ == "__main__":
27
+ #args input-image input-mask output
28
+ image = Image.open(sys.argv[1])
29
+ mask = Image.open(sys.argv[2])
30
+ output = process_image(image,mask)
31
+ output.save(sys.argv[3])
requirements.txt ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ spaces
2
+ numpy
3
+ torch
4
+ diffusers
5
+ accelerate
6
+ transformers
7
+ sentencepiece