toby007 commited on
Commit
63f6eb9
·
1 Parent(s): e51059c

update code

Browse files
Files changed (3) hide show
  1. README.md +10 -32
  2. handler.py +14 -40
  3. requirements.txt +5 -5
README.md CHANGED
@@ -1,42 +1,20 @@
1
- # AI 形象照生成服务 - 基于 FLUX.1-Fill-dev 模型
2
 
3
- 本项目基于 `black-forest-labs/FLUX.1-Fill-dev` 模型,部署为 Hugging Face Inference Endpoint 服务,支持**图生图(image-to-image / inpainting)**应用场景:
4
 
5
- - 替换背景
6
- - 风格转换
7
- - 商务形象照生成
8
 
9
- ## 🔧 接口调用说明(POST /)
10
-
11
- 接口输入格式(JSON):
12
 
 
13
  ```json
14
  {
15
  "inputs": {
16
- "prompt": "商务风格形象照,穿蓝色西装,微笑,高清写实风格",
17
- "image": "<base64 PNG 图像>",
18
- "mask": "<base64 PNG 掩码图像>"
 
 
19
  }
20
  }
21
  ```
22
-
23
- 返回格式:
24
-
25
- ```json
26
- {
27
- "image": "<base64 PNG 图像>"
28
- }
29
- ```
30
-
31
- ## 💡 掩码说明
32
- - 图像和掩码需为相同尺寸
33
- - 掩码中**白色部分为需要替换的区域**
34
-
35
- ## 🚀 示例场景
36
-
37
- - 用户上传自拍照片,并通过 mask 指定区域(如衣服、背景)
38
- - 后端根据 prompt 生成对应风格的合成图
39
-
40
- ---
41
-
42
- 本部署服务基于 diffusers 实现,更多信息参考:https://huggingface.co/black-forest-labs/FLUX.1-Fill-dev
 
1
+ # FLUX.1-Fill-dev Custom Inference Endpoint
2
 
3
+ This repository is set up to deploy a custom Hugging Face Inference Endpoint using the StableDiffusionInstructPix2PixPipeline, enabling image-to-image transformation with prompt guidance.
4
 
5
+ ## How to Use
 
 
6
 
7
+ Send a POST request with base64-encoded `image` and your `prompt` to get an enhanced version of the image.
 
 
8
 
9
+ ## Input example:
10
  ```json
11
  {
12
  "inputs": {
13
+ "prompt": "高清艺术风格头像",
14
+ "image": "<base64-encoded-image>",
15
+ "steps": 30,
16
+ "guidance_scale": 7.5,
17
+ "image_guidance_scale": 1.5
18
  }
19
  }
20
  ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
handler.py CHANGED
@@ -1,21 +1,17 @@
1
- from diffusers import StableDiffusionInpaintPipeline
2
  from PIL import Image
3
  import torch
4
  import base64
5
  from io import BytesIO
6
 
7
- # 使用 huggingface repo id 形式加载(确保路径正确)
8
- pipe = StableDiffusionInpaintPipeline.from_pretrained(
9
- "shangguanyanyan/flux1-fill-dev-custom", # 请确认仓库ID无误
10
  torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
11
  ).to("cuda" if torch.cuda.is_available() else "cpu")
12
 
13
  def decode_image(b64_string):
14
- try:
15
- image_data = base64.b64decode(b64_string)
16
- return Image.open(BytesIO(image_data)).convert("RGB")
17
- except Exception as e:
18
- raise ValueError(f"解码图像失败: {str(e)}")
19
 
20
  def encode_image(image):
21
  buffer = BytesIO()
@@ -25,45 +21,23 @@ def encode_image(image):
25
  def handler(data):
26
  try:
27
  inputs = data.get("inputs", {})
28
- prompt = inputs.get("prompt", "高清写实风格人物形象照")
29
-
30
  image_b64 = inputs.get("image")
31
- mask_b64 = inputs.get("mask")
32
- if not image_b64 or not mask_b64:
33
- raise ValueError("缺少必要的 image 或 mask 参数")
34
 
35
- image = decode_image(image_b64)
36
- mask = decode_image(mask_b64)
37
-
38
- # 默认参数(支持调整)
39
- height = int(inputs.get("height", image.height))
40
- width = int(inputs.get("width", image.width))
41
- steps = int(inputs.get("num_inference_steps", 30))
42
- cfg_scale = float(inputs.get("guidance_scale", 7.5))
43
 
44
- image = image.resize((width, height))
45
- mask = mask.resize((width, height))
46
 
47
  result = pipe(
48
  prompt=prompt,
49
  image=image,
50
- mask_image=mask,
51
- height=height,
52
- width=width,
53
- num_inference_steps=steps,
54
- guidance_scale=cfg_scale
55
  ).images[0]
56
 
57
- return {
58
- "status": "success",
59
- "image": encode_image(result),
60
- "meta": {
61
- "prompt": prompt,
62
- "size": f"{width}x{height}",
63
- "steps": steps,
64
- "cfg_scale": cfg_scale
65
- }
66
- }
67
 
68
  except Exception as e:
69
- return {"status": "failed", "error": str(e)}
 
1
+ from diffusers import StableDiffusionInstructPix2PixPipeline
2
  from PIL import Image
3
  import torch
4
  import base64
5
  from io import BytesIO
6
 
7
+ pipe = StableDiffusionInstructPix2PixPipeline.from_pretrained(
8
+ "shangguanyanyan/flux1-fill-dev-custom",
 
9
  torch_dtype=torch.float16 if torch.cuda.is_available() else torch.float32
10
  ).to("cuda" if torch.cuda.is_available() else "cpu")
11
 
12
  def decode_image(b64_string):
13
+ image_data = base64.b64decode(b64_string)
14
+ return Image.open(BytesIO(image_data)).convert("RGB")
 
 
 
15
 
16
  def encode_image(image):
17
  buffer = BytesIO()
 
21
  def handler(data):
22
  try:
23
  inputs = data.get("inputs", {})
24
+ prompt = inputs.get("prompt", "写实风格形象照")
 
25
  image_b64 = inputs.get("image")
 
 
 
26
 
27
+ if not image_b64:
28
+ return {"error": "缺少 image 参数", "status": "failed"}
 
 
 
 
 
 
29
 
30
+ image = decode_image(image_b64)
 
31
 
32
  result = pipe(
33
  prompt=prompt,
34
  image=image,
35
+ num_inference_steps=int(inputs.get("steps", 30)),
36
+ guidance_scale=float(inputs.get("guidance_scale", 7.5)),
37
+ image_guidance_scale=float(inputs.get("image_guidance_scale", 1.5))
 
 
38
  ).images[0]
39
 
40
+ return {"image": encode_image(result), "status": "success"}
 
 
 
 
 
 
 
 
 
41
 
42
  except Exception as e:
43
+ return {"error": str(e), "status": "failed"}
requirements.txt CHANGED
@@ -1,5 +1,5 @@
1
- torch>=2.1.0
2
- transformers>=4.35.0
3
- diffusers>=0.26.3
4
- accelerate>=0.25.0
5
- Pillow>=10.0.0
 
1
+ diffusers>=0.14.0
2
+ transformers
3
+ torch
4
+ accelerate
5
+ safetensors