|
@@ -0,0 +1,627 @@
|
|
|
|
|
+import copy
|
|
|
|
|
+import os.path
|
|
|
|
|
+from .other.module_online_data import GetOnlineData
|
|
|
|
|
+import time
|
|
|
|
|
+from .other.log import MyLogger
|
|
|
|
|
+import os
|
|
|
|
|
+from .remove_bg_pixian import RemoveBgPiXian
|
|
|
|
|
+from PIL import Image
|
|
|
|
|
+from .other.pic import Picture
|
|
|
|
|
+from .other.remove_bg_ali import RemoveBgALi
|
|
|
|
|
+import cv2
|
|
|
|
|
+import numpy as np
|
|
|
|
|
+from middleware import UnicornException
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class Base(object):
|
|
|
|
|
+
|
|
|
|
|
+ def __init__(self, image_data, lock, windows, num):
|
|
|
|
|
+ self.lock = lock
|
|
|
|
|
+ self.image_data = image_data
|
|
|
|
|
+ self.num = num
|
|
|
|
|
+ self.windows = windows
|
|
|
|
|
+ self.get_online_data = GetOnlineData()
|
|
|
|
|
+ self.file_path = image_data["file_path"]
|
|
|
|
|
+ self.file_name = image_data["file_name"]
|
|
|
|
|
+ self.file = os.path.split(self.file_path)[1]
|
|
|
|
|
+ self.is_once_data = {}
|
|
|
|
|
+ self.logger = MyLogger().logger
|
|
|
|
|
+
|
|
|
|
|
+ def add_log(self, text, _type="info"):
|
|
|
|
|
+ self.logger.info(
|
|
|
|
|
+ "第{}个,图片名称:{},内容:{}".format(self.num, self.file, text)
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ def show_image_info(self, data):
|
|
|
|
|
+ data["file_path"] = self.file_path
|
|
|
|
|
+ with self.lock:
|
|
|
|
|
+ data = {
|
|
|
|
|
+ "_type": "show_image_item_info",
|
|
|
|
|
+ "data": data,
|
|
|
|
|
+ }
|
|
|
|
|
+ # self.windows.signal_data.emit(data)
|
|
|
|
|
+
|
|
|
|
|
+ def send_info(
|
|
|
|
|
+ self,
|
|
|
|
|
+ text="",
|
|
|
|
|
+ is_success=None,
|
|
|
|
|
+ _type="show_text_browser",
|
|
|
|
|
+ need_point_return=False,
|
|
|
|
|
+ ):
|
|
|
|
|
+ with self.lock:
|
|
|
|
|
+ if is_success is not None:
|
|
|
|
|
+ if is_success:
|
|
|
|
|
+ processing_failed = 0
|
|
|
|
|
+ processing_successfully = 1
|
|
|
|
|
+ else:
|
|
|
|
|
+ processing_failed = 1
|
|
|
|
|
+ processing_successfully = 0
|
|
|
|
|
+ # 分数返回
|
|
|
|
|
+ if need_point_return:
|
|
|
|
|
+ # 分数返回
|
|
|
|
|
+ if self.is_once("add_point"):
|
|
|
|
|
+ print(
|
|
|
|
|
+ "第{}个,图片名称:{},内容:{}".format(
|
|
|
|
|
+ self.num, self.file, "扣分返回"
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ self.dispose_point(_type="add")
|
|
|
|
|
+ self.refresh_times(cumulative_frequency_times_change=-1)
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+ # self.windows.signal_data.emit({"_type": "schedule",
|
|
|
|
|
+ # "data": {"processing_failed": processing_failed,
|
|
|
|
|
+ # "processing_successfully": processing_successfully,
|
|
|
|
|
+ # }})
|
|
|
|
|
+
|
|
|
|
|
+ if text:
|
|
|
|
|
+ data = {
|
|
|
|
|
+ "_type": "show_text_browser",
|
|
|
|
|
+ "data": text,
|
|
|
|
|
+ }
|
|
|
|
|
+ # self.windows.signal_data.emit(data)
|
|
|
|
|
+
|
|
|
|
|
+ def check_path(self, _path):
|
|
|
|
|
+ if not os.path.exists(_path):
|
|
|
|
|
+ os.mkdir(_path)
|
|
|
|
|
+ return True
|
|
|
|
|
+
|
|
|
|
|
+ def is_once(self, key):
|
|
|
|
|
+ if key not in self.is_once_data:
|
|
|
|
|
+ self.is_once_data[key] = 0
|
|
|
|
|
+ return True
|
|
|
|
|
+ return False
|
|
|
|
|
+
|
|
|
|
|
+ def refresh_times(self, cumulative_frequency_times_change=0):
|
|
|
|
|
+ data = {
|
|
|
|
|
+ "_type": "refresh_times",
|
|
|
|
|
+ "data": {
|
|
|
|
|
+ "cumulative_frequency_times_change": cumulative_frequency_times_change
|
|
|
|
|
+ },
|
|
|
|
|
+ }
|
|
|
|
|
+ # self.windows.signal_data.emit(data)
|
|
|
|
|
+ pass
|
|
|
|
|
+
|
|
|
|
|
+ def dispose_point(self, _type):
|
|
|
|
|
+ n = 3
|
|
|
|
|
+ while n:
|
|
|
|
|
+ n -= 1
|
|
|
|
|
+ try:
|
|
|
|
|
+ _r = self.get_online_data.dispose_point(_type)
|
|
|
|
|
+ balance = _r["data"]["balance"]
|
|
|
|
|
+ return True
|
|
|
|
|
+ except:
|
|
|
|
|
+ time.sleep(0.5)
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
|
|
+ return False
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class DealOneImage(Base):
|
|
|
|
|
+ def __init__(self, image_data, lock, windows, num):
|
|
|
|
|
+ super().__init__(image_data, lock, windows, num)
|
|
|
|
|
+ self.image_data = image_data
|
|
|
|
|
+ self.lock = lock
|
|
|
|
|
+ self.windows = windows
|
|
|
|
|
+ self.num = num
|
|
|
|
|
+ self.file_path = image_data["file_path"]
|
|
|
|
|
+ self.file = os.path.split(self.file_path)[1]
|
|
|
|
|
+ self.root_path = image_data["root_path"]
|
|
|
|
|
+ self.r_pixian = RemoveBgPiXian()
|
|
|
|
|
+ self.file_name = image_data["file_name"]
|
|
|
|
|
+
|
|
|
|
|
+ def run(self):
|
|
|
|
|
+ # 直接调用抠图
|
|
|
|
|
+ # 1、增加获取key,2、key需要加密、3、429报错 重试再来拿一个KEY
|
|
|
|
|
+ self.add_log("开始处理")
|
|
|
|
|
+ self.show_image_info(
|
|
|
|
|
+ {
|
|
|
|
|
+ "text": "处理中",
|
|
|
|
|
+ "info": "",
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ remaining_times = self.get_online_data.get_cutout_image_times().get("balance")
|
|
|
|
|
+ print("remaining_times", remaining_times)
|
|
|
|
|
+ if remaining_times <= 0:
|
|
|
|
|
+ # self.send_info(text="次数不足,处理失败", is_success=False)
|
|
|
|
|
+ raise UnicornException("次数不足,处理失败")
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ # 检查图片上传是否有结束
|
|
|
|
|
+ n = 60
|
|
|
|
|
+ while 1:
|
|
|
|
|
+ if self.windows.state != 1:
|
|
|
|
|
+ # self.show_image_info({"text": "已取消", "info": "", })
|
|
|
|
|
+ # self.send_info(text="用户主动终止", is_success=False)
|
|
|
|
|
+ raise UnicornException("用户主动终止")
|
|
|
|
|
+ return
|
|
|
|
|
+ n -= 1
|
|
|
|
|
+ # print(n)
|
|
|
|
|
+ if self.file_path in self.windows.upload_pic_dict:
|
|
|
|
|
+ break
|
|
|
|
|
+
|
|
|
|
|
+ else:
|
|
|
|
|
+ time.sleep(1)
|
|
|
|
|
+ if n <= 0:
|
|
|
|
|
+ text = "处理超时"
|
|
|
|
|
+ self.send_info(text=text, is_success=False)
|
|
|
|
|
+
|
|
|
|
|
+ _data = {
|
|
|
|
|
+ "text": "出错/超时",
|
|
|
|
|
+ "info": "处理超时",
|
|
|
|
|
+ }
|
|
|
|
|
+ self.show_image_info(_data)
|
|
|
|
|
+ return
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
|
|
+ s = time.time()
|
|
|
|
|
+ # print(self.upload_pic_dict[file_path])
|
|
|
|
|
+ _flag = self.windows.upload_pic_dict[self.file_path]["flag"]
|
|
|
|
|
+ if not _flag:
|
|
|
|
|
+ self.add_log("未查到上传的图片地址")
|
|
|
|
|
+ _data = {
|
|
|
|
|
+ "text": "出错/超时",
|
|
|
|
|
+ "info": "上传错误",
|
|
|
|
|
+ }
|
|
|
|
|
+ self.show_image_info(_data)
|
|
|
|
|
+ # self.send_info(text="上传错误", is_success=False)
|
|
|
|
|
+ raise UnicornException("上传错误")
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ image_deal_info = self.windows.upload_pic_dict[self.file_path][
|
|
|
|
|
+ "image_deal_info"
|
|
|
|
|
+ ]
|
|
|
|
|
+ original_im = self.windows.upload_pic_dict[self.file_path]["_im"]
|
|
|
|
|
+
|
|
|
|
|
+ self.show_image_info(
|
|
|
|
|
+ {
|
|
|
|
|
+ "text": "开始抠图",
|
|
|
|
|
+ "info": "",
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ self.add_log("抠图中")
|
|
|
|
|
+
|
|
|
|
|
+ with self.lock:
|
|
|
|
|
+ self.windows.is_upload_pic_num -= 1
|
|
|
|
|
+
|
|
|
|
|
+ # 抠图
|
|
|
|
|
+ out_root_path = "{}/已扣图".format(self.root_path)
|
|
|
|
|
+ self.check_path(out_root_path)
|
|
|
|
|
+
|
|
|
|
|
+ # 直接调用pixian
|
|
|
|
|
+ # second_cut_image,_ = self.r_pixian.run_by_image_url(image_url)
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+ balance = self.get_online_data.get_cutout_image_times()["balance"]
|
|
|
|
|
+ self.add_log("查询balance:{}成功".format(balance))
|
|
|
|
|
+ if balance <= 0:
|
|
|
|
|
+ self.add_log("次数不足,处理失败")
|
|
|
|
|
+ raise UnicornException("次数不足,处理失败")
|
|
|
|
|
+ self.send_info(text="次数不足,处理失败", is_success=False)
|
|
|
|
|
+ return
|
|
|
|
|
+ except:
|
|
|
|
|
+ self.add_log("查询balance失败")
|
|
|
|
|
+ raise UnicornException("查询balance失败")
|
|
|
|
|
+ self.send_info(text="查询balance失败", is_success=False)
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ n = 0
|
|
|
|
|
+ while 1:
|
|
|
|
|
+ # 获取key
|
|
|
|
|
+ if self.windows.state != 1:
|
|
|
|
|
+ self.show_image_info(
|
|
|
|
|
+ {
|
|
|
|
|
+ "text": "已取消",
|
|
|
|
|
+ "info": "",
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ raise UnicornException("用户主动终止")
|
|
|
|
|
+ # self.send_info(text="用户主动终止", is_success=False)
|
|
|
|
|
+ return
|
|
|
|
|
+ n += 1
|
|
|
|
|
+ data = self.get_online_data.get_key_secret()
|
|
|
|
|
+ key = (data["api_info"]["api_key"], data["api_info"]["api_serect"])
|
|
|
|
|
+ self.add_log("查询key成功")
|
|
|
|
|
+
|
|
|
|
|
+ if not key:
|
|
|
|
|
+ _data = {
|
|
|
|
|
+ "text": "出错/超时",
|
|
|
|
|
+ "info": "多次获取key失败",
|
|
|
|
|
+ }
|
|
|
|
|
+ self.add_log(text="多次获取key失败")
|
|
|
|
|
+ self.show_image_info(_data)
|
|
|
|
|
+ raise UnicornException("处理失败,请联系管理员")
|
|
|
|
|
+ self.send_info(text="处理失败,请联系管理员", is_success=False)
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ if self.is_once("sub_point"):
|
|
|
|
|
+ # 调用扣分
|
|
|
|
|
+ with self.lock:
|
|
|
|
|
+ self.refresh_times(cumulative_frequency_times_change=1)
|
|
|
|
|
+ f = self.dispose_point(_type="sub")
|
|
|
|
|
+ if not f:
|
|
|
|
|
+ self.add_log(text="多次获取调用余额扣减失败")
|
|
|
|
|
+ raise UnicornException("多次获取调用余额扣减失败")
|
|
|
|
|
+ self.send_info(text="多次获取调用余额扣减失败", is_success=False)
|
|
|
|
|
+ _data = {
|
|
|
|
|
+ "text": "出错/超时",
|
|
|
|
|
+ "info": "多次获取调用余额扣减失败",
|
|
|
|
|
+ }
|
|
|
|
|
+ self.show_image_info(_data)
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ pixian_cutout_data = self.r_pixian.run_by_image_im(original_im, key)
|
|
|
|
|
+ # pixian_cutout_data = {"status_code":200}
|
|
|
|
|
+
|
|
|
|
|
+ if pixian_cutout_data["status_code"] == 200:
|
|
|
|
|
+ second_cut_image = pixian_cutout_data["im"]
|
|
|
|
|
+ # second_cut_image.save("xx.png")
|
|
|
|
|
+ # second_cut_image = Image.open("xx.png")
|
|
|
|
|
+ self.add_log(text="调用抠图完成")
|
|
|
|
|
+ break
|
|
|
|
|
+
|
|
|
|
|
+ elif pixian_cutout_data["status_code"] == 402:
|
|
|
|
|
+ if n >= 2:
|
|
|
|
|
+ _data = {
|
|
|
|
|
+ "text": "出错/超时",
|
|
|
|
|
+ "info": "多次抠图失败:{}".format(
|
|
|
|
|
+ pixian_cutout_data["status_code"]
|
|
|
|
|
+ ),
|
|
|
|
|
+ }
|
|
|
|
|
+ self.add_log(
|
|
|
|
|
+ text="多次抠图失败:{}".format(pixian_cutout_data["status_code"])
|
|
|
|
|
+ )
|
|
|
|
|
+ self.show_image_info(_data)
|
|
|
|
|
+ self.send_info(
|
|
|
|
|
+ text="处理失败,请联系管理员",
|
|
|
|
|
+ is_success=False,
|
|
|
|
|
+ need_point_return=True,
|
|
|
|
|
+ )
|
|
|
|
|
+ raise UnicornException("多次获取调用余额扣减失败")
|
|
|
|
|
+ if self.is_once("余额不足报错"):
|
|
|
|
|
+ # todo 余额不足报错,钉钉消息通知
|
|
|
|
|
+ self.get_online_data.send_message(
|
|
|
|
|
+ "Pixian:{} 余额不足".format(key)
|
|
|
|
|
+ )
|
|
|
|
|
+ pass
|
|
|
|
|
+ return
|
|
|
|
|
+ self.add_log(
|
|
|
|
|
+ text="抠图失败:{},延迟6秒".format(
|
|
|
|
|
+ pixian_cutout_data["status_code"]
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ time.sleep(6)
|
|
|
|
|
+ continue
|
|
|
|
|
+
|
|
|
|
|
+ elif pixian_cutout_data["status_code"] == 429:
|
|
|
|
|
+ if n >= 2:
|
|
|
|
|
+ _data = {
|
|
|
|
|
+ "text": "出错/超时",
|
|
|
|
|
+ "info": "多次抠图失败:{}".format(
|
|
|
|
|
+ pixian_cutout_data["status_code"]
|
|
|
|
|
+ ),
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ self.show_image_info(_data)
|
|
|
|
|
+ self.add_log(
|
|
|
|
|
+ text="多次抠图失败:{}".format(pixian_cutout_data["status_code"])
|
|
|
|
|
+ )
|
|
|
|
|
+ self.send_info(
|
|
|
|
|
+ text="处理失败,请联系管理员",
|
|
|
|
|
+ is_success=False,
|
|
|
|
|
+ need_point_return=True,
|
|
|
|
|
+ )
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ self.add_log(
|
|
|
|
|
+ text="抠图失败:{},延迟10秒".format(
|
|
|
|
|
+ pixian_cutout_data["status_code"]
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ time.sleep(10)
|
|
|
|
|
+ continue
|
|
|
|
|
+ else:
|
|
|
|
|
+ _data = {
|
|
|
|
|
+ "text": "出错/超时",
|
|
|
|
|
+ "info": "抠图异常",
|
|
|
|
|
+ }
|
|
|
|
|
+ self.show_image_info(_data)
|
|
|
|
|
+ self.send_info(
|
|
|
|
|
+ text="处理失败,请联系管理员",
|
|
|
|
|
+ is_success=False,
|
|
|
|
|
+ need_point_return=True,
|
|
|
|
|
+ )
|
|
|
|
|
+ if "message" in pixian_cutout_data:
|
|
|
|
|
+ text = "抠图异常,code:{},message:{}".format(
|
|
|
|
|
+ pixian_cutout_data["status_code"], pixian_cutout_data["message"]
|
|
|
|
|
+ )
|
|
|
|
|
+ else:
|
|
|
|
|
+ text = "抠图异常,code:{}".format(
|
|
|
|
|
+ pixian_cutout_data["status_code"]
|
|
|
|
|
+ )
|
|
|
|
|
+ self.add_log(text)
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ # 拼接处理
|
|
|
|
|
+ # print("耗时1:", time.time() - s)
|
|
|
|
|
+
|
|
|
|
|
+ try:
|
|
|
|
|
+ out_path = "{}/{}.png".format(out_root_path, self.file_name)
|
|
|
|
|
+ if image_deal_info["二次抠图是否缩放"]:
|
|
|
|
|
+ # print("图片尺寸还原")
|
|
|
|
|
+ self.add_log(text="图片尺寸进行还原")
|
|
|
|
|
+ original_im = image_deal_info["抠图扩边后PIL对象"]
|
|
|
|
|
+ second_cut_image = self.picture_resize_to_original(
|
|
|
|
|
+ second_cut_image, original_im
|
|
|
|
|
+ )
|
|
|
|
|
+ # second_cut_image = second_cut_image.resize(image_deal_info["抠图扩边后图片大小"])
|
|
|
|
|
+ # 创建空白图片并粘贴回去
|
|
|
|
|
+ _img_im = Image.new(
|
|
|
|
|
+ mode="RGBA", size=image_deal_info["原始图片大小"], color=(0, 0, 0, 0)
|
|
|
|
|
+ )
|
|
|
|
|
+ _img_im.paste(
|
|
|
|
|
+ second_cut_image,
|
|
|
|
|
+ box=(
|
|
|
|
|
+ image_deal_info["抠图扩边后位置"][0],
|
|
|
|
|
+ image_deal_info["抠图扩边后位置"][1],
|
|
|
|
|
+ ),
|
|
|
|
|
+ )
|
|
|
|
|
+ _img_im.save(out_path)
|
|
|
|
|
+
|
|
|
|
|
+ except BaseException as e:
|
|
|
|
|
+ # print(e)
|
|
|
|
|
+ text = "{} 图片处理错误,代码44".format(e)
|
|
|
|
|
+ self.add_log(text)
|
|
|
|
|
+ self.send_info(text=text, is_success=False, need_point_return=True)
|
|
|
|
|
+ _data = {
|
|
|
|
|
+ "text": "出错/超时",
|
|
|
|
|
+ "info": text,
|
|
|
|
|
+ }
|
|
|
|
|
+ self.show_image_info(_data)
|
|
|
|
|
+ return
|
|
|
|
|
+
|
|
|
|
|
+ self.add_log(text="本张耗时:{}".format(time.time() - s))
|
|
|
|
|
+ self.send_info(text="抠图已完成", is_success=True)
|
|
|
|
|
+ self.show_image_info(
|
|
|
|
|
+ {
|
|
|
|
|
+ "text": "已完成",
|
|
|
|
|
+ "info": "",
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+
|
|
|
|
|
+ def picture_resize_to_original(self, _img, original_im):
|
|
|
|
|
+ """
|
|
|
|
|
+
|
|
|
|
|
+ Parameters
|
|
|
|
|
+ ----------
|
|
|
|
|
+ _img 需要还原的PIL对象
|
|
|
|
|
+ original_im 原图对象
|
|
|
|
|
+
|
|
|
|
|
+ Returns
|
|
|
|
|
+ -------
|
|
|
|
|
+
|
|
|
|
|
+ """
|
|
|
|
|
+
|
|
|
|
|
+ # 将抠图结果转成mask
|
|
|
|
|
+ # 将抠图结果放大到原始图大小
|
|
|
|
|
+ _img = _img.resize(original_im.size)
|
|
|
|
|
+ new_big_mask = Image.new("RGB", _img.size, (0, 0, 0))
|
|
|
|
|
+ white = Image.new("RGB", _img.size, (255, 255, 255))
|
|
|
|
|
+ new_big_mask.paste(white, mask=_img.split()[3])
|
|
|
|
|
+
|
|
|
|
|
+ # ---------制作选区缩小的mask
|
|
|
|
|
+ mask = cv2.cvtColor(
|
|
|
|
|
+ np.asarray(new_big_mask), cv2.COLOR_BGR2GRAY
|
|
|
|
|
+ ) # 将PIL 格式转换为 CV对象
|
|
|
|
|
+ mask[mask != 255] = 0
|
|
|
|
|
+ # 黑白反转
|
|
|
|
|
+ # mask = 255 - mask
|
|
|
|
|
+ # 选区缩小10
|
|
|
|
|
+ kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (10, 10))
|
|
|
|
|
+ erode_im = cv2.morphologyEx(mask, cv2.MORPH_ERODE, kernel)
|
|
|
|
|
+
|
|
|
|
|
+ # -------再进行抠图处理
|
|
|
|
|
+ mask = Image.fromarray(
|
|
|
|
|
+ cv2.cvtColor(erode_im, cv2.COLOR_GRAY2RGBA)
|
|
|
|
|
+ ) # CV 对象转 PIL
|
|
|
|
|
+ transparent_im = Image.new("RGBA", original_im.size, (0, 0, 0, 0))
|
|
|
|
|
+ transparent_im.paste(original_im, (0, 0), mask.convert("L"))
|
|
|
|
|
+ # 上述抠图结果进行拼接
|
|
|
|
|
+ _img.paste(transparent_im, (0, 0), transparent_im)
|
|
|
|
|
+
|
|
|
|
|
+ return _img
|
|
|
|
|
+
|
|
|
|
|
+
|
|
|
|
|
+class DealOneImageBeforehand(Base):
|
|
|
|
|
+ def __init__(self, image_data, lock, windows, num):
|
|
|
|
|
+ super().__init__(image_data, lock, windows, num)
|
|
|
|
|
+ self.image_data = image_data
|
|
|
|
|
+ self.lock = lock
|
|
|
|
|
+ self.windows = windows
|
|
|
|
|
+ self.get_online_data = GetOnlineData()
|
|
|
|
|
+ self.num = num
|
|
|
|
|
+ self.file_path = image_data["file_path"]
|
|
|
|
|
+ self.file = os.path.split(self.file_path)[1]
|
|
|
|
|
+ self.root_path = image_data["root_path"]
|
|
|
|
|
+ self.r_ali = RemoveBgALi()
|
|
|
|
|
+ self.file_name = image_data["file_name"]
|
|
|
|
|
+
|
|
|
|
|
+ def run(self):
|
|
|
|
|
+ # 增加阿里调用报错的重试机制
|
|
|
|
|
+ # a = 1/0
|
|
|
|
|
+ # raise "11111111111111111"
|
|
|
|
|
+ while 1:
|
|
|
|
|
+ if self.windows.state != 1:
|
|
|
|
|
+ self.show_image_info(
|
|
|
|
|
+ {
|
|
|
|
|
+ "text": "已取消",
|
|
|
|
|
+ "info": "",
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ return
|
|
|
|
|
+ with self.lock:
|
|
|
|
|
+ if self.windows.is_upload_pic_num >= 4:
|
|
|
|
|
+ f = False
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.windows.is_upload_pic_num += 1
|
|
|
|
|
+ f = True
|
|
|
|
|
+ if f:
|
|
|
|
|
+ break
|
|
|
|
|
+ else:
|
|
|
|
|
+ time.sleep(1)
|
|
|
|
|
+ continue
|
|
|
|
|
+ image_deal_info = {}
|
|
|
|
|
+ try:
|
|
|
|
|
+ _data = {
|
|
|
|
|
+ "text": "开始上传",
|
|
|
|
|
+ "info": "",
|
|
|
|
|
+ }
|
|
|
|
|
+ self.show_image_info(_data)
|
|
|
|
|
+ cut_image, image_deal_info = self.get_image_cut()
|
|
|
|
|
+
|
|
|
|
|
+ f = True
|
|
|
|
|
+ url = ""
|
|
|
|
|
+ self.show_image_info(
|
|
|
|
|
+ {
|
|
|
|
|
+ "text": "上传成功",
|
|
|
|
|
+ "info": "",
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ except BaseException as e:
|
|
|
|
|
+ # print(e)
|
|
|
|
|
+ self.show_image_info(
|
|
|
|
|
+ {
|
|
|
|
|
+ "text": "上传出错",
|
|
|
|
|
+ "info": "{}".format(e),
|
|
|
|
|
+ }
|
|
|
|
|
+ )
|
|
|
|
|
+ f = False
|
|
|
|
|
+ url = ""
|
|
|
|
|
+ cut_image = ""
|
|
|
|
|
+
|
|
|
|
|
+ # cut_image.save("1.jpg",format="JPEG")
|
|
|
|
|
+ # raise 1
|
|
|
|
|
+
|
|
|
|
|
+ with self.lock:
|
|
|
|
|
+ self.windows.upload_pic_dict[self.file_path] = {
|
|
|
|
|
+ "url": url,
|
|
|
|
|
+ "image_deal_info": image_deal_info,
|
|
|
|
|
+ "flag": f,
|
|
|
|
|
+ "_im": cut_image,
|
|
|
|
|
+ }
|
|
|
|
|
+
|
|
|
|
|
+ def get_image_cut(self):
|
|
|
|
|
+ original_pic = Picture(self.file_path)
|
|
|
|
|
+ original_pic.im = self.get_image_orientation(original_pic.im)
|
|
|
|
|
+ original_pic.x, original_pic.y = original_pic.im.size
|
|
|
|
|
+
|
|
|
|
|
+ original_pic.im = original_pic.im.convert("RGB")
|
|
|
|
|
+ image_deal_info = {}
|
|
|
|
|
+ image_deal_info["原始图片大小"] = (original_pic.x, original_pic.y)
|
|
|
|
|
+ if original_pic.x * original_pic.y < 1000000:
|
|
|
|
|
+ cut_image = original_pic.im
|
|
|
|
|
+ image_deal_info["抠图扩边后图片大小"] = cut_image.size
|
|
|
|
|
+ image_deal_info["二次抠图是否缩放"] = False
|
|
|
|
|
+ image_deal_info["抠图扩边后位置"] = (0, 0, original_pic.x, original_pic.y)
|
|
|
|
|
+ else:
|
|
|
|
|
+ self.add_log("开始预抠图处理")
|
|
|
|
|
+ cut_image = self.r_ali.get_image_cut(
|
|
|
|
|
+ file_path=None, out_file_path=None, original_im=original_pic.im
|
|
|
|
|
+ )
|
|
|
|
|
+ # cut_image.save("XX1.png")
|
|
|
|
|
+
|
|
|
|
|
+ self.add_log("预抠图处理结束")
|
|
|
|
|
+
|
|
|
|
|
+ x1, y1, x2, y2 = cut_image.getbbox()
|
|
|
|
|
+ image_deal_info["鞋子原始位置"] = (x1, y1, x2, y2)
|
|
|
|
|
+ o_w, o_h = cut_image.size
|
|
|
|
|
+ image_deal_info["鞋子原始抠图后大小"] = (o_w, o_h)
|
|
|
|
|
+ # 扩边处理
|
|
|
|
|
+ _w, _h = x2 - x1, y2 - y1
|
|
|
|
|
+ out_px = 0.025
|
|
|
|
|
+ _w, _h = int(out_px * _w), int(out_px * _h)
|
|
|
|
|
+ n_x1, n_y1, n_x2, n_y2 = x1 - _w, y1 - _h, x2 + _w, y2 + _h
|
|
|
|
|
+ if n_x1 < 0:
|
|
|
|
|
+ n_x1 = 0
|
|
|
|
|
+ if n_y1 < 0:
|
|
|
|
|
+ n_y1 = 0
|
|
|
|
|
+ if n_x2 > o_w:
|
|
|
|
|
+ n_x2 = o_w
|
|
|
|
|
+ if n_y2 > o_h:
|
|
|
|
|
+ n_y2 = o_h
|
|
|
|
|
+ image_deal_info["抠图扩边后位置"] = (n_x1, n_y1, n_x2, n_y2)
|
|
|
|
|
+ cut_image = original_pic.im.crop(image_deal_info["抠图扩边后位置"])
|
|
|
|
|
+
|
|
|
|
|
+ image_deal_info["抠图扩边后图片大小"] = cut_image.size
|
|
|
|
|
+ x, y = image_deal_info["抠图扩边后图片大小"]
|
|
|
|
|
+ # max_size = 32000000
|
|
|
|
|
+ max_size = 12000000
|
|
|
|
|
+ if x * y > max_size:
|
|
|
|
|
+ r = max_size / (x * y)
|
|
|
|
|
+ size = (int(x * r), int(y * r))
|
|
|
|
|
+ self.add_log(
|
|
|
|
|
+ text="图片进行压缩,压缩前:{},压缩后:{}".format(
|
|
|
|
|
+ image_deal_info["抠图扩边后图片大小"], size
|
|
|
|
|
+ )
|
|
|
|
|
+ )
|
|
|
|
|
+ image_deal_info["抠图扩边后PIL对象"] = copy.deepcopy(cut_image)
|
|
|
|
|
+ cut_image = cut_image.resize(size=size)
|
|
|
|
|
+ # print(cut_image.size)
|
|
|
|
|
+ # print(image_deal_info["抠图扩边后PIL对象"].size)
|
|
|
|
|
+ image_deal_info["二次抠图是否缩放"] = True
|
|
|
|
|
+ else:
|
|
|
|
|
+ image_deal_info["二次抠图是否缩放"] = False
|
|
|
|
|
+ return cut_image, image_deal_info
|
|
|
|
|
+
|
|
|
|
|
+ def get_image_orientation(self, img):
|
|
|
|
|
+ # 获取EXIF数据
|
|
|
|
|
+ exif = img._getexif()
|
|
|
|
|
+ if exif is not None:
|
|
|
|
|
+ # EXIF标签274对应的是Orientation
|
|
|
|
|
+ orientation = exif.get(0x0112)
|
|
|
|
|
+ if orientation == 2:
|
|
|
|
|
+ # 水平翻转
|
|
|
|
|
+ img = img.transpose(Image.FLIP_LEFT_RIGHT)
|
|
|
|
|
+ elif orientation == 3:
|
|
|
|
|
+ # 旋转180度
|
|
|
|
|
+ img = img.rotate(180, expand=True)
|
|
|
|
|
+ elif orientation == 4:
|
|
|
|
|
+ # 垂直翻转
|
|
|
|
|
+ img = img.transpose(Image.FLIP_TOP_BOTTOM)
|
|
|
|
|
+ elif orientation == 5:
|
|
|
|
|
+ # 水平翻转后顺时针旋转90度
|
|
|
|
|
+ img = img.transpose(Image.FLIP_LEFT_RIGHT).transpose(Image.ROTATE_270)
|
|
|
|
|
+ elif orientation == 6:
|
|
|
|
|
+ # 顺时针旋转90度
|
|
|
|
|
+ img = img.transpose(Image.ROTATE_270)
|
|
|
|
|
+ elif orientation == 7:
|
|
|
|
|
+ # 水平翻转后逆时针旋转90度
|
|
|
|
|
+ img = img.transpose(Image.FLIP_LEFT_RIGHT).transpose(Image.ROTATE_90)
|
|
|
|
|
+ elif orientation == 8:
|
|
|
|
|
+ # 逆时针旋转90度
|
|
|
|
|
+ img = img.transpose(Image.ROTATE_90)
|
|
|
|
|
+ else:
|
|
|
|
|
+ print("没有EXIF数据或没有方向信息")
|
|
|
|
|
+ orientation = 1
|
|
|
|
|
+
|
|
|
|
|
+ return img
|