Browse Source

```
feat(api): 扩展图片组合选项至组合26

- 在API配置中将图片顺序选项从组合5扩展到组合26
- 更新所有相关API端点以支持新的图片组合选项

refactor(base_deal): 优化图片顺序验证逻辑

- 将硬编码的图片选项数组重构为动态列表
- 使用格式化字符串动态生成错误消息
- 统一各服务中的图片顺序验证逻辑

feat(remove_bg_pixian): 集成pixian.ai背景移除服务

- 添加settings模块依赖
- 实现通过URL和文件上传的背景移除功能
- 添加图片上传到OSS并转换域名的逻辑
- 增加API密钥切换支持
- 添加异常处理和状态码返回
```

rambo 3 weeks ago
parent
commit
30c5df09e5

+ 2 - 2
python/api.py

@@ -473,7 +473,7 @@ async def _build_config_data(params, goods_art_no_arrays):
     config_data = {
         "image_dir": limit_path,
         "image_order": (
-            "俯视,侧视,后跟,鞋底,内里,组合,组合2,组合3,组合4,组合5"
+            "俯视,侧视,后跟,鞋底,内里,组合,组合2,组合3,组合4,组合5,组合6,组合7,组合8,组合9,组合10,组合11,组合12,组合13,组合14,组合15,组合16,组合17,组合18,组合19,组合20,组合21,组合22,组合23,组合24,组合25,组合26"
             if not params.template_image_order
             else params.template_image_order
         ),
@@ -1618,7 +1618,7 @@ async def remove_background(params:PhotoRecordRemoveBackground):
     config_data = {
         "image_dir": limit_path,
         "image_order": (
-            "俯视,侧视,后跟,鞋底,内里,组合,组合2,组合3,组合4,组合5"
+            "俯视,侧视,后跟,鞋底,内里,组合,组合2,组合3,组合4,组合5,组合6,组合7,组合8,组合9,组合10,组合11,组合12,组合13,组合14,组合15,组合16,组合17,组合18,组合19,组合20,组合21,组合22,组合23,组合24,组合25,组合26"
         ),
         "goods_art_no": "",
         "goods_art_nos": goods_art_no_arrays,

+ 38 - 2
python/service/auto_deal_pics/base_deal.py

@@ -168,8 +168,44 @@ class BaseDealImage(object):
             return {'code': 1, 'msg': '图片位置与顺序重复,请检查您的输入'}
 
         for val in imageOrderList:
-            if val not in ["俯视", "侧视", "后跟", "鞋底", "内里", "组合", "组合2", "组合3", "组合4", "组合5"]:
-                return {'code': 1, 'msg': '可选项为:俯视,侧视,后跟,鞋底,内里,组合,组合2,组合3,组合4,组合5'}
+            image_orders = [
+                "俯视",
+                "侧视",
+                "后跟",
+                "鞋底",
+                "内里",
+                "组合",
+                "组合2",
+                "组合3",
+                "组合4",
+                "组合5",
+                "组合6",
+                "组合7",
+                "组合8",
+                "组合9",
+                "组合10",
+                "组合11",
+                "组合12",
+                "组合13",
+                "组合14",
+                "组合15",
+                "组合16",
+                "组合17",
+                "组合18",
+                "组合19",
+                "组合20",
+                "组合22",
+                "组合23",
+                "组合24",
+                "组合25",
+                "组合26",
+            ]
+            if val not in image_orders:
+                image_orders_str = ','.join(map(str, image_orders))
+                return {
+                    "code": 1,
+                    "msg": f"可选项为:{image_orders_str}",
+                }
 
         if resize_image_view not in imageOrderList:
             return {'code': 1, 'msg': '缩小的步骤必须是你填写的图片顺序中'}

+ 25 - 3
python/service/base_deal.py

@@ -242,7 +242,7 @@ class BaseDealImage(object):
             return {"code": 1, "msg": "图片位置与顺序重复,请检查您的输入"}
 
         for val in imageOrderList:
-            if val not in [
+            image_orders = [
                 "俯视",
                 "侧视",
                 "后跟",
@@ -253,10 +253,32 @@ class BaseDealImage(object):
                 "组合3",
                 "组合4",
                 "组合5",
-            ]:
+                "组合6",
+                "组合7",
+                "组合8",
+                "组合9",
+                "组合10",
+                "组合11",
+                "组合12",
+                "组合13",
+                "组合14",
+                "组合15",
+                "组合16",
+                "组合17",
+                "组合18",
+                "组合19",
+                "组合20",
+                "组合22",
+                "组合23",
+                "组合24",
+                "组合25",
+                "组合26",
+            ]
+            if val not in image_orders:
+                image_orders_str = ','.join(map(str, image_orders))
                 return {
                     "code": 1,
-                    "msg": "可选项为:俯视,侧视,后跟,鞋底,内里,组合,组合2,组合3,组合4,组合5",
+                    "msg": f"可选项为:{image_orders_str}",
                 }
 
         if resize_image_view not in imageOrderList:

+ 38 - 2
python/service/match_and_cutout_mode_control/base_deal_image_v2.py

@@ -181,8 +181,44 @@ class BaseDealImage(object):
             return {'code': 1, 'msg': '图片位置与顺序重复,请检查您的输入'}
 
         for val in imageOrderList:
-            if val not in ["俯视", "侧视", "后跟", "鞋底", "内里", "组合", "组合2", "组合3", "组合4", "组合5"]:
-                return {'code': 1, 'msg': '可选项为:俯视,侧视,后跟,鞋底,内里,组合,组合2,组合3,组合4,组合5'}
+            image_orders = [
+                "俯视",
+                "侧视",
+                "后跟",
+                "鞋底",
+                "内里",
+                "组合",
+                "组合2",
+                "组合3",
+                "组合4",
+                "组合5",
+                "组合6",
+                "组合7",
+                "组合8",
+                "组合9",
+                "组合10",
+                "组合11",
+                "组合12",
+                "组合13",
+                "组合14",
+                "组合15",
+                "组合16",
+                "组合17",
+                "组合18",
+                "组合19",
+                "组合20",
+                "组合22",
+                "组合23",
+                "组合24",
+                "组合25",
+                "组合26",
+            ]
+            if val not in image_orders:
+                image_orders_str = ','.join(map(str, image_orders))
+                return {
+                    "code": 1,
+                    "msg": f"可选项为:{image_orders_str}",
+                }
 
         if resize_image_view not in imageOrderList:
             return {'code': 1, 'msg': '缩小的步骤必须是你填写的图片顺序中'}

+ 64 - 12
python/service/remove_bg_pixian.py

@@ -4,7 +4,7 @@ from PIL import Image
 from .remove_bg_ali import RemoveBgALi
 import requests
 from io import BytesIO
-
+import settings
 
 class Segment(object):
     def __init__(self):
@@ -36,20 +36,41 @@ class Segment(object):
         else:
             return None, response.content
 
-    def get_no_bg_goods_by_url(self, url):
+    def get_no_bg_goods_by_url(self, url,key):
+        if key:
+            # 切换key
+            auth = key
+            # auth = (self.k, self.s)
+        else:
+            auth = (self.k, self.s)
         response = requests.post(
-            'https://api.pixian.ai/api/v2/remove-background',
+            'https://3api.valimart.net/api/v2/remove-background',
             data={
                 'image.url': url
             },
-            auth=(self.k, self.s)
+            auth=auth
         )
 
-        if response.status_code == requests.codes.ok:
-            return response.content, ""
-        else:
-            print("response.status_code:", response.status_code)
-            return None, response.content
+        data = {"im": None,
+                "status_code": response.status_code, }
+
+        try:
+            if response.status_code == requests.codes.ok:
+                data["im"] = Image.open(BytesIO(response.content))
+                return data
+            else:
+                print("response.status_code:", response.status_code)
+                data = {"im": None,
+                        "status_code": "time_out",
+                        "message":"处理失败"
+                        }
+                return data
+        except BaseException as e:
+            data = {"im": None,
+                    "status_code": "time_out",
+                    "message":"{}".format(e)
+                    }
+            return data
 
     def get_no_bg_goods(self, file_path=None, _im=None, key=None):
         im = _im
@@ -70,7 +91,7 @@ class Segment(object):
 
         try:
             response = requests.post(
-                'https://api.pixian.ai/api/v2/remove-background',
+                'https://3api.valimart.net/api/v2/remove-background',
                 files={'image': img},
                 data={
                     # Add more upload options here
@@ -150,9 +171,40 @@ class RemoveBgPiXian(object):
             return _img_im, None
         else:
             return None, _
-
+    def upload_image_by_io(self, image_pil:Image) -> str:
+        # post_headers = {"Authorization": settings.Authorization}
+        im = image_pil
+        img = BytesIO()
+        try:
+            im.save(img, format='JPEG')  # format: PNG or JPEG
+        except:
+            im.save(img, format='PNG')  # format: PNG or JPEG
+        img.seek(0)  # rewind to the start
+        try:
+            url = settings.DOMAIN + "/api/upload"
+            resultData = requests.post(
+                url, files={"file": img},
+                timeout=100
+            ).json()
+            return resultData["data"]["url"]
+        except Exception as e:
+            print("upload_image_by_io error:", e)
+            return None
     def run_by_image_im(self, im, key):
-        return self.segment.get_no_bg_goods(_im=im, key=key)
+        image_url = self.upload_image_by_io(im)
+        if image_url is None:
+            data = {"im": None,
+                        "status_code": "time_out",
+                        "message":"图片上传失败"
+                        }
+            return data
+        # image_url
+        # 把image_url中的ossimg.valimart.net
+        # 替换为img-cuts.valimart.net
+        print("image_url  1:", image_url)
+        image_url = image_url.replace('ossimg.valimart.net', 'img-cuts.valimart.net')
+        print("image_url  2:", image_url)
+        return self.segment.get_no_bg_goods_by_url(url=image_url,key=key)
 
     def get_image_cut(self, file_path, out_file_path=None, original_im=None, image_preprocessing=False, is_test=False):
         if original_im: