base_deal.py 56 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192
  1. import json
  2. from .module_generate_goods_art_no_table import GenerateGoodsArtNoTable
  3. from func_timeout import FunctionTimedOut
  4. from .grenerate_main_image_test import GeneratePic
  5. from threading import Lock
  6. import settings
  7. from collections import defaultdict
  8. from .remove_bg_ali import RemoveBgALi, Picture
  9. from .deal_cutout import DealCutout
  10. import time
  11. from .image_pic_deal import OnePicDeal
  12. from natsort import natsorted,ns
  13. import os
  14. import shutil
  15. import exifread
  16. import datetime
  17. from databases import DeviceConfig,SqlQuery,CRUD
  18. from model.photo_record import PhotoRecord
  19. import requests
  20. import copy
  21. """
  22. 照片自动货号匹配 将图片放置在指定文件夹下,并自动对应不同的货号进行整理
  23. """
  24. _Type = ['.png', '.PNG', '.jpg', '.JPG', '.gif', '.GIF', ".jpge", ".JPGE"]
  25. class BaseDealImage(object):
  26. def __init__(self, image_dir=None,token=None):
  27. self.token = token
  28. self.goods_images_count_dict = defaultdict(int)
  29. # 数据模型
  30. # self.data_mode_auto_deal_pics = DataModeAutoDealPics()
  31. self.image_dir = image_dir
  32. pass
  33. def run_main(self, all_goods_art_no_folder_data, callback_func=None, cutout_mode=None,
  34. resize_image_view=None, windows=None, logo_path=None, image_order_list=None):
  35. # 对所有缺失已抠图的进行抠图处理
  36. self.run_cutout_image(all_goods_art_no_folder_data=all_goods_art_no_folder_data,
  37. callback_func=callback_func,
  38. cutout_mode=cutout_mode,
  39. windows=windows,
  40. )
  41. error_num = 0
  42. successful_num = 0
  43. for goods_art_no_folder_data in all_goods_art_no_folder_data:
  44. if goods_art_no_folder_data["label"] != "待处理":
  45. continue
  46. if windows:
  47. if windows.state != 1:
  48. break
  49. folder_name = goods_art_no_folder_data["folder_name"]
  50. callback_func("开始处理文件夹========== {} ".format(folder_name))
  51. if settings.IS_TEST:
  52. flag = self.shoes_run_one_folder_to_deal(goods_art_no_folder_data=goods_art_no_folder_data,
  53. resize_image_view=resize_image_view,
  54. logo_path=logo_path,
  55. image_order_list=image_order_list,
  56. callback_func=callback_func,
  57. windows=windows,
  58. )
  59. if flag is None:
  60. callback_func("货号:{} 数据异常".format(folder_name))
  61. else:
  62. if flag:
  63. successful_num += 1
  64. callback_func("货号:{} 图片生成处理成功".format(folder_name))
  65. else:
  66. error_num += 1
  67. callback_func("货号:{} 图片生成处理失败".format(folder_name))
  68. else:
  69. try:
  70. flag = self.shoes_run_one_folder_to_deal(goods_art_no_folder_data=goods_art_no_folder_data,
  71. resize_image_view=resize_image_view,
  72. logo_path=logo_path,
  73. image_order_list=image_order_list,
  74. callback_func=callback_func,
  75. windows=windows,
  76. )
  77. if flag is None:
  78. callback_func("货号:{} 数据异常".format(folder_name))
  79. else:
  80. if flag:
  81. successful_num += 1
  82. callback_func("货号:{} 图片生成处理成功".format(folder_name))
  83. else:
  84. error_num += 1
  85. callback_func("货号:{} 图片生成处理失败".format(folder_name))
  86. except BaseException as e:
  87. error_num += 1
  88. import traceback
  89. traceback.print_exc()
  90. callback_func("货号:{} 图片生成处理异常,原因:{}".format(folder_name, e))
  91. callback_func("处理成功:{}个,失败:{}".format(successful_num, error_num))
  92. def checkImageAmount(self, image_dir: str, amount: int, todo_goods_art_no_folder_name_list=None) -> dict:
  93. result = {'code': 0, 'msg': '', 'data': {}}
  94. for goods_art_no_folder in self.list_dir(image_dir):
  95. # 指定内容检查
  96. if todo_goods_art_no_folder_name_list is not None:
  97. if goods_art_no_folder not in todo_goods_art_no_folder_name_list:
  98. continue
  99. if not os.path.isdir("{}/{}".format(image_dir, goods_art_no_folder)):
  100. continue
  101. if "软件" in goods_art_no_folder:
  102. continue
  103. if "无法" in goods_art_no_folder:
  104. continue
  105. if "原始图" not in self.list_dir("{}/{}".format(image_dir, goods_art_no_folder)):
  106. result['data'][goods_art_no_folder] = '文件夹下,没有 原始图 文件夹\n'
  107. continue
  108. # 计算单个文件夹原图数量
  109. images = [x for x in self.list_dir("{}/{}/原始图".format(image_dir, goods_art_no_folder))]
  110. image_num = 0
  111. for pic_file_name in images:
  112. _, e = os.path.splitext(pic_file_name)
  113. if e in _Type:
  114. image_num += 1
  115. # if self.number_pictures != 0:
  116. if image_num > amount:
  117. result['data'][goods_art_no_folder] = '货号图片大于{}张~\n'.format(amount)
  118. if image_num < 2:
  119. result['data'][goods_art_no_folder] = '货号图片小于于2张~\n'
  120. if result['data']:
  121. result['code'] = 1
  122. return result
  123. def check_folders_image_amount(self, all_goods_art_no_folder_data, image_order_list):
  124. print("*****************check_folders_image_amount************************")
  125. amount = len(image_order_list)
  126. # print("图片数量检查===>", amount)
  127. message = ""
  128. for goods_art_no_folder_data in all_goods_art_no_folder_data:
  129. if goods_art_no_folder_data["label"] != "待处理":
  130. continue
  131. folder_path = goods_art_no_folder_data["folder_path"]
  132. folder_name = goods_art_no_folder_data["folder_name"]
  133. images = [x for x in self.list_dir("{}/原始图".format(folder_path))]
  134. image_num = 0
  135. for pic_file_name in images:
  136. _, e = os.path.splitext(pic_file_name)
  137. if e in _Type:
  138. image_num += 1
  139. # print("图片数量判断===>", image_num)
  140. # if image_num > amount:
  141. # goods_art_no_folder_data["label"] = "错误"
  142. # message += '货号{}:图片大于{}张~\n'.format(folder_name, amount)
  143. # if image_num < 2:
  144. # message += '货号{}:图片小于于2张~\n'.format(folder_name)
  145. return all_goods_art_no_folder_data, message
  146. def check_one_folder_image_amount(self, folder_data, amount: int):
  147. print("*****************check_one_folder_image_amount************************")
  148. # 计算单个文件夹原图数量
  149. images = [x for x in self.list_dir("{}/原始图".format(folder_data["folder_path"]))]
  150. image_num = 0
  151. for pic_file_name in images:
  152. _, e = os.path.splitext(pic_file_name)
  153. if e in _Type:
  154. image_num += 1
  155. if image_num > amount:
  156. return False, '货号{}:图片大于{}张~\n'.format(folder_data["folder_name"], amount)
  157. if image_num < 2:
  158. return False, '货号{}:图片小于于2张~\n'.format(folder_data["folder_name"])
  159. return True, ""
  160. # 指定的图片顺序
  161. def getImageOrder(self, image_order: str, resize_image_view: str):
  162. imageOrderList = image_order.replace(",", ",").replace(' ', '').replace('图', '').split(",")
  163. if len(set(imageOrderList)) != len(imageOrderList):
  164. return {'code': 1, 'msg': '图片位置与顺序重复,请检查您的输入'}
  165. for val in imageOrderList:
  166. if val not in ["俯视", "侧视", "后跟", "鞋底", "内里", "组合", "组合2", "组合3", "组合4", "组合5"]:
  167. return {'code': 1, 'msg': '可选项为:俯视,侧视,后跟,鞋底,内里,组合,组合2,组合3,组合4,组合5'}
  168. if resize_image_view not in imageOrderList:
  169. return {'code': 1, 'msg': '缩小的步骤必须是你填写的图片顺序中'}
  170. return {'code': 0, 'msg': 'sucess', 'imageOrderList': imageOrderList}
  171. def shoes_run_one_folder_to_deal(self,
  172. goods_art_no_folder_data,
  173. image_order_list: list,
  174. resize_image_view: str,
  175. logo_path="",
  176. windows=None,
  177. callback_func=None):
  178. """
  179. 操作步骤:
  180. 1、查询每个图片的角度
  181. 2、
  182. """
  183. is_successful = True
  184. folder_path = goods_art_no_folder_data["folder_path"]
  185. folder_name = goods_art_no_folder_data["folder_name"]
  186. all_original_images = self.get_images("{}/原始图".format(folder_path))
  187. self.check_path('{}/800x800'.format(folder_path))
  188. self.crate_all_folders(folder_path)
  189. print("all_original_images====>",all_original_images)
  190. if not all_original_images:
  191. return None
  192. # _ = ["俯视", "侧视", "后跟", "鞋底", "内里"]
  193. for index, image_dict in enumerate(all_original_images):
  194. if index < len(image_order_list):
  195. image_dict["image_view"] = image_order_list[index]
  196. else:
  197. image_dict["image_view"] = '其他{}'.format(len(image_order_list) - index + 1)
  198. # ====================处理所有图片的顺序====================
  199. # ["俯视", "侧视", "后跟", "鞋底", "内里"]
  200. _config = {"俯视": 1,
  201. "侧视": 2,
  202. "后跟": 3,
  203. "鞋底": 4,
  204. "内里": 5, }
  205. r = time.time()
  206. n = 0
  207. _index = 0
  208. # 检查是否有重复的角度
  209. _d_views = []
  210. f = True
  211. for image_dict in all_original_images:
  212. n += 1
  213. _index += 1
  214. image_dict["old_file_name"] = image_dict["file_name"]
  215. image_dict["random_name"] = "{}-{}".format(r, n)
  216. if image_dict["image_view"] in _config:
  217. if image_dict["image_view"] not in _d_views:
  218. _d_views.append(image_dict["image_view"])
  219. else:
  220. callback_func("货号:{} 处理失败".format(folder_name))
  221. # self.show_progress_detail("货号图{} 存在多个{} 角度~".format(goods_art_no_folder, image_dict["image_view"]))
  222. return None
  223. image_dict["index"] = _config[image_dict["image_view"]]
  224. else:
  225. image_dict["index"] = _index
  226. all_original_images.sort(key=lambda x: x["index"])
  227. # ==========直接进行处理=============
  228. i_n = 0
  229. image_index = 0 # 图片顺序
  230. is_image_deal_mode = 0
  231. # 删除目录再新建
  232. if os.path.exists('{}/阴影图处理'.format(folder_path)):
  233. shutil.rmtree('{}/阴影图处理'.format(folder_path))
  234. self.crate_all_folders(folder_path)
  235. print(
  236. "***************all_original_images*********************",
  237. all_original_images,
  238. )
  239. for image_dict in all_original_images:
  240. if windows:
  241. if windows.state != 1:
  242. return None
  243. i_n += 1
  244. image_index += 1
  245. original_image_path = "{}/原始图/{}{}".format(folder_path, image_dict["file_name"], image_dict["e"])
  246. file_name = image_dict["file_name"]
  247. print("正在处理,货号:{}".format(folder_path))
  248. # self.show_progress_detail("正在处理,货号:{}".format(file_name))
  249. # 该文件在800images下没有时,则进行生成新的抠图
  250. # 检查是否存在已抠图文件,如没有再去抠图
  251. original_move_bg_image_path = "{}/原始图_已抠图/{}{}".format(folder_path, image_dict["file_name"], ".png")
  252. print(
  253. f"*****************此处判断鞋子是否为左右脚====>{image_index}<======={is_image_deal_mode}=======>**********************"
  254. )
  255. # 此处判断鞋子是否为左右脚
  256. if image_index == 1:
  257. is_image_deal_mode = 0
  258. print("开始识别左右脚=========>")
  259. if OnePicDeal(self.token).check_shoe_is_right(
  260. image_path=original_move_bg_image_path
  261. ):
  262. is_image_deal_mode = 1 # 1表示要镜像,0表示不做镜像
  263. print(
  264. "*************************进行800image 生成********************************************"
  265. )
  266. """进行800image 生成"""
  267. generate_pic = GeneratePic()
  268. print(
  269. "*************************进行800image 结束====>>>>********************************************"
  270. )
  271. out_pci_mode = "." + settings.getSysConfigs(
  272. "basic_configs", "image_out_format", "png"
  273. )
  274. if out_pci_mode == ".jpg":
  275. out_path = "{}/800x800/{}{}".format(folder_path, file_name, ".jpg")
  276. elif out_pci_mode == ".png":
  277. out_path = "{}/800x800/{}{}".format(folder_path, file_name, ".png")
  278. else:
  279. out_path = "{}/800x800/{}{}".format(
  280. folder_path, file_name, out_pci_mode
  281. )
  282. out_process_path_1 = "{}/阴影图处理/{}_{}_阴影{}".format(folder_path, file_name,
  283. image_dict["image_view"], ".png")
  284. out_process_path_2 = "{}/阴影图处理/{}_{}_抠图{}".format(folder_path, file_name,
  285. image_dict["image_view"], ".png")
  286. resize_mode = 1
  287. max_box = None
  288. print("------------1", image_dict["image_view"], resize_image_view)
  289. if image_dict["image_view"] == resize_image_view:
  290. print(image_dict["image_view"], resize_image_view)
  291. resize_mode = 2
  292. if (
  293. settings.getSysConfigs("other_configs", "product_type", "鞋类")
  294. == "皮具"
  295. ):
  296. max_box = (1000, 1200)
  297. out_pic_size = (
  298. [1600]
  299. if settings.getSysConfigs("basic_configs", "main_image_size", [1600])
  300. == ""
  301. else settings.getSysConfigs("basic_configs", "main_image_size", [1600])
  302. ) # 主图大小
  303. if resize_mode == 2:
  304. print(
  305. "参数打印================》",
  306. is_image_deal_mode,
  307. resize_mode,
  308. out_pic_size,
  309. True if i_n == 1 else False,
  310. max_box,
  311. )
  312. print("**********123456********************")
  313. curve_mask = True if "俯视" in image_order_list else False
  314. if not generate_pic.run(
  315. image_path=original_image_path,
  316. cut_image_path=original_move_bg_image_path,
  317. out_path=out_path,
  318. image_deal_mode=is_image_deal_mode,
  319. resize_mode=resize_mode,
  320. out_pic_size=out_pic_size,
  321. is_logo=True if i_n == 1 else False,
  322. out_process_path_1=out_process_path_1,
  323. out_process_path_2=out_process_path_2,
  324. max_box=max_box,
  325. logo_path=logo_path,
  326. curve_mask=curve_mask,
  327. ):
  328. print("**********222222222222222222222222222********************")
  329. is_successful = False
  330. if is_successful:
  331. return True
  332. else:
  333. return False
  334. def to_upload_pic(self, file_path, is_resize=True):
  335. file_name = os.path.split(file_path)[1]
  336. e = os.path.splitext(file_name)[1][1:]
  337. im = Picture(file_path)
  338. if im.x > 500:
  339. im.resize(width=500)
  340. _ = {"jpg": "JPEG",
  341. "JPG": "JPEG",
  342. "JPEG": "JPEG",
  343. "jpeg": "JPEG",
  344. "png": "PNG",
  345. "PNG": "PNG", }
  346. e = _[e]
  347. image_io = im.save_to_io(e)
  348. goods_data = {"file_path": os.path.split(file_path)[1],
  349. "image_io": image_io,
  350. "e": e
  351. }
  352. url = self.data_mode_image_cut.get_online_data.upload_pic(goods_data=goods_data)
  353. return url
  354. def get_images(self, path):
  355. image_list = [] # 过滤非图片数据
  356. for _file in self.list_dir(path):
  357. file_name, e = os.path.splitext(_file)
  358. if e in _Type:
  359. image_list.append({"file_path": "{}/{}".format(path, _file),
  360. "file_name": file_name,
  361. "e": e})
  362. return image_list
  363. def crate_all_folders(self, root_path):
  364. path_list = ["800x800", "原始图_已抠图", "阴影图处理"]
  365. for i in path_list:
  366. path = "{}/{}".format(root_path, i)
  367. self.check_path(path)
  368. def run_cutout_image(self, all_goods_art_no_folder_data, callback_func=None, cutout_mode=1, windows=None):
  369. """
  370. 处理所有的抠图
  371. """
  372. callback_func('开始处理抠图~')
  373. error_goods_art_no_folder = []
  374. for goods_art_no_folder_data in all_goods_art_no_folder_data:
  375. if goods_art_no_folder_data["label"] != "待处理":
  376. continue
  377. folder_path = goods_art_no_folder_data["folder_path"]
  378. self.crate_all_folders(folder_path)
  379. # 检查是否存在已抠图文件,如没有再去抠图
  380. images = [x for x in self.list_dir("{}/原始图".format(folder_path))]
  381. cutImageList = []
  382. for pic_file_name in images:
  383. if windows:
  384. if windows.state != 1:
  385. break
  386. # 根据名称判断,没有抠图过的,进行统计
  387. file_name, suffix = os.path.splitext(pic_file_name)
  388. if suffix in _Type:
  389. original_image_path = "{}/原始图/{}".format(folder_path, pic_file_name)
  390. original_move_bg_image_path = "{}/原始图_已抠图/{}{}".format(folder_path, file_name, ".png")
  391. if not os.path.exists(original_move_bg_image_path):
  392. # 没有抠图文件,进行抠图生成
  393. callback_func("正在抠图 货号:{}".format(file_name))
  394. if cutout_mode == '2':
  395. cutImageList.append({
  396. "file_name": file_name, # 文件名
  397. "file_e": suffix, # 后缀,.jpg
  398. "file_path": original_image_path, # 完整路径
  399. "file": '{}{}'.format(file_name, suffix), # 图片文件名,带后缀
  400. "need_cutout": True, # 必须,需要抠图
  401. "out_path": original_move_bg_image_path
  402. })
  403. else:
  404. remove_pic_ins = RemoveBgALi()
  405. if settings.IS_TEST:
  406. im = remove_pic_ins.get_image_cut(file_path=original_image_path,
  407. out_file_path=original_move_bg_image_path)
  408. else:
  409. try:
  410. im = remove_pic_ins.get_image_cut(file_path=original_image_path,
  411. out_file_path=original_move_bg_image_path)
  412. except FunctionTimedOut as f:
  413. callback_func("货号图{} 抠图处理超时~".format(file_name))
  414. im = None
  415. except BaseException as e:
  416. callback_func("货号图{} 抠图处理失败,原因{}".format(file_name, e))
  417. im = None
  418. if not im:
  419. callback_func("货号图{} 抠图处理失败~".format(file_name))
  420. continue
  421. else:
  422. callback_func("货号图{} 抠图完成~".format(file_name))
  423. if cutout_mode == '2':
  424. dealCutout = DealCutout(windows=None)
  425. dealCutout.need_cutout_images = cutImageList
  426. dealCutout.run()
  427. while True:
  428. time.sleep(1)
  429. if windows:
  430. if windows.state != 1:
  431. break
  432. if dealCutout.state == 3:
  433. if len(dealCutout.resultData) != len(cutImageList):
  434. error_goods_art_no_folder.append(folder_path)
  435. break
  436. if error_goods_art_no_folder:
  437. print("以下货号抠图失败~\n {}".format(error_goods_art_no_folder))
  438. callback_func("以下货号抠图失败~\n {}".format(error_goods_art_no_folder))
  439. else:
  440. callback_func("完成抠图处理")
  441. def checkCutoutImage(self, image_dir: str, todo_goods_art_no_folder_name_list=None):
  442. """
  443. 进行图片检查,不合规的直接提示
  444. """
  445. error_goods_art_no_folder = []
  446. self.check_path("{}/软件-处理失败".format(image_dir))
  447. for goods_art_no_folder in self.list_dir(image_dir):
  448. # 指定内容检查
  449. if todo_goods_art_no_folder_name_list is not None:
  450. if goods_art_no_folder not in todo_goods_art_no_folder_name_list:
  451. continue
  452. if not os.path.isdir("{}/{}".format(image_dir, goods_art_no_folder)):
  453. continue
  454. if "软件" in goods_art_no_folder:
  455. continue
  456. if "无法" in goods_art_no_folder:
  457. continue
  458. if "原始图" not in self.list_dir("{}/{}".format(image_dir, goods_art_no_folder)):
  459. error_goods_art_no_folder.append(goods_art_no_folder)
  460. continue
  461. self.check_path("{}/{}/原始图_已抠图".format(image_dir, goods_art_no_folder))
  462. self.check_path("{}/{}/800x800".format(image_dir, goods_art_no_folder))
  463. self.check_path("{}/{}/阴影图处理".format(image_dir, goods_art_no_folder))
  464. if error_goods_art_no_folder:
  465. self.move_folders(path_list=["{}/{}".format(self.image_dir, x) for x in error_goods_art_no_folder],
  466. target_folder="{}/软件-处理失败".format(self.image_dir))
  467. return False
  468. def move_folders(self, path_list, target_folder):
  469. for source_folder in path_list:
  470. shutil.move(source_folder, target_folder)
  471. def rename_folder_for_hqt(self, all_goods_art_no_folder_data):
  472. """
  473. 步骤:
  474. 规整红蜻蜓的文件名
  475. 重新按文件名进行命名
  476. """
  477. goods_art_no_list = []
  478. for goods_art_no_folder_data in all_goods_art_no_folder_data:
  479. if "@" not in goods_art_no_folder_data["folder_name"]:
  480. goods_art_no_folder_data["label"] = "待处理"
  481. goods_art_no_list.append(goods_art_no_folder_data["folder_name"])
  482. else:
  483. goods_art_no_folder_data["label"] = "不处理"
  484. if goods_art_no_list:
  485. # goods_art_no_dict 文件夹与货号的字典
  486. goods_art_no_dict = self.get_data_from_hqt_with_goods_art_no(
  487. goods_art_no_list=goods_art_no_list)
  488. for goods_art_no_folder_data in all_goods_art_no_folder_data:
  489. if goods_art_no_folder_data["label"] != "待处理":
  490. continue
  491. goods_art_no_folder = goods_art_no_folder_data["folder_name"]
  492. if goods_art_no_folder in goods_art_no_dict:
  493. print(goods_art_no_folder)
  494. old_folder_path = goods_art_no_folder_data["folder_path"]
  495. new_folder_name = "{}@NUM{}".format(goods_art_no_folder,
  496. goods_art_no_dict[goods_art_no_folder]["编号"])
  497. new_folder_path = "{}/{}".format(goods_art_no_folder_data["root_path"], new_folder_name)
  498. try:
  499. os.rename(old_folder_path, new_folder_path)
  500. goods_art_no_folder_data["folder_path"] = new_folder_path
  501. goods_art_no_folder_data["folder_name"] = new_folder_path
  502. goods_art_no_folder_data["label"] = "待处理"
  503. except BaseException as e:
  504. goods_art_no_folder_data["label"] = "不处理"
  505. print("521 文件夹重名命失败:{}".format(e))
  506. # 重新规整修改图片名称
  507. for goods_art_no_folder_data in all_goods_art_no_folder_data:
  508. if goods_art_no_folder_data["label"] != "待处理":
  509. continue
  510. goods_art_no_folder = goods_art_no_folder_data["folder_name"]
  511. _img_all = self.list_dir("{}/原始图".format(goods_art_no_folder_data["folder_path"]))
  512. index = 0
  513. for _file in _img_all:
  514. file_name, suffix = os.path.splitext(_file)
  515. if suffix in _Type:
  516. index += 1
  517. folder_path = goods_art_no_folder_data["folder_path"]
  518. new_file_name = "{}({}){}".format(goods_art_no_folder, index, suffix)
  519. new_path = "{}/原始图/{}".format(folder_path, new_file_name)
  520. old_path = "{}/原始图/{}".format(folder_path, _file)
  521. crop_new_path = "{}/原始图_已抠图/{}".format(folder_path, "{}({}).png".format(goods_art_no_folder, index))
  522. crop_old_path = "{}/原始图_已抠图/{}".format(folder_path, "{}.png".format(file_name))
  523. if old_path != new_path:
  524. # 存在货号命名错误的,进行修正
  525. try:
  526. if os.path.exists(old_path):
  527. os.rename(old_path, new_path)
  528. if os.path.exists(crop_old_path):
  529. os.rename(crop_old_path, crop_new_path)
  530. except BaseException as e:
  531. goods_art_no_folder_data["label"] = "不处理"
  532. print("550 文件夹重名命失败:{}".format(e))
  533. def cutImagePiju(self, image_dir: str, image_order='', is_check_number=True, is_filter=True, resize_image_view='后跟',
  534. callback_func=None, event=None, todo_goods_art_no_folder_name_list=None):
  535. """
  536. 1、遍历文件夹,基于生成的结果图看哪些需要进行抠图等处理
  537. 2、压缩并上传平台获取抠图
  538. 3、抠图处理成白底图
  539. 4、做成800*800/200*200
  540. :return:
  541. """
  542. logo_path = ""
  543. res = self.getImageOrder(image_order=image_order, resize_image_view=resize_image_view)
  544. if res['code'] != 0:
  545. callback_func(res['msg'])
  546. return {'code': 1, 'msg': res['msg']}
  547. imageOrderList = res['imageOrderList']
  548. """扫描文档,检查有哪些需要进行抠图等处理"""
  549. self.lock = Lock()
  550. to_do_images_total = 0
  551. error_goods_art_no_folder = []
  552. for goods_art_no_folder in self.list_dir(image_dir):
  553. # 指定内容检查
  554. if todo_goods_art_no_folder_name_list is not None:
  555. if goods_art_no_folder not in todo_goods_art_no_folder_name_list:
  556. continue
  557. if not os.path.isdir("{}/{}".format(image_dir, goods_art_no_folder)):
  558. continue
  559. self.check_path("{}/{}/原始图".format(image_dir, goods_art_no_folder))
  560. self.check_path("{}/{}/原始图_已抠图".format(image_dir, goods_art_no_folder))
  561. self.check_path("{}/{}/800x800".format(image_dir, goods_art_no_folder))
  562. self.check_path("{}/{}/阴影图处理".format(image_dir, goods_art_no_folder))
  563. # 遍历原始图片文件夹
  564. all_original_images = [x for x in
  565. self.list_dir(
  566. "{}/{}/原始图".format(image_dir, goods_art_no_folder))]
  567. # 检查已抠图文件夹
  568. all_moved_images = [os.path.splitext(x)[0] for x in
  569. self.list_dir(
  570. "{}/{}/原始图_已抠图".format(image_dir, goods_art_no_folder))]
  571. all_800images = [os.path.splitext(x)[0] for x in
  572. self.list_dir(
  573. "{}/{}/800x800".format(image_dir, goods_art_no_folder))]
  574. if is_check_number and len(imageOrderList) != len(all_original_images):
  575. callback_func("{} 文件夹下图片数量与订单数量不一致,请检查!".format(goods_art_no_folder))
  576. return {'code': 1, 'msg': '{} 文件夹下图片数量与订单数量不一致,请检查!'.format(goods_art_no_folder)}
  577. all_800images = []
  578. image_num = 0
  579. for pic_file_name in all_original_images:
  580. if pic_file_name not in all_800images:
  581. # 根据名称判断,没有抠图过的,进行统计
  582. _, e = os.path.splitext(pic_file_name)
  583. print(e)
  584. if e in _Type:
  585. image_num += 1
  586. print("----------》", goods_art_no_folder, pic_file_name)
  587. to_do_images_total += 1
  588. # if image_num > 5:
  589. # error_goods_art_no_folder.append(goods_art_no_folder)
  590. # if error_goods_art_no_folder:
  591. # self.show_progress_detail("以下货号图片张数超过5张~\n {}".format(error_goods_art_no_folder))
  592. # self.set_state(state_value=2)
  593. # return
  594. if to_do_images_total > 0:
  595. # self.progress_sign.emit({"type": "处理图片 抠图、加工等", "progress_bar_value": 0})
  596. for goods_art_no_folder in self.list_dir(image_dir):
  597. # 指定内容检查
  598. if todo_goods_art_no_folder_name_list is not None:
  599. if goods_art_no_folder not in todo_goods_art_no_folder_name_list:
  600. continue
  601. if not os.path.isdir('{}/{}'.format(image_dir, goods_art_no_folder)):
  602. continue
  603. self.run_one_folder_to_deal(goods_art_no_folder=goods_art_no_folder,
  604. image_dir=image_dir,
  605. image_order=image_order,
  606. resize_image_view=resize_image_view,
  607. callback_func=callback_func,
  608. logo_path=logo_path,
  609. )
  610. else:
  611. # self.show_progress_detail("没有需要处理的图片~")
  612. callback_func('没有需要处理的图片~')
  613. # self.set_state(state_value=2)
  614. return {'code': 0, 'msg': 'ok'}
  615. def run_one_folder_to_deal(self, goods_art_no_folder, image_dir, image_order, resize_image_view,
  616. callback_func=None, logo_path=""):
  617. _img_all = self.list_dir("{}/{}/原始图".format(image_dir, goods_art_no_folder))
  618. all_original_images = [] # 过滤非图片数据
  619. index = 0
  620. for _file in _img_all:
  621. file_name, e = os.path.splitext(_file)
  622. if e in _Type:
  623. index += 1
  624. new_file_name = "{}({}){}".format(goods_art_no_folder, index, e)
  625. new_path = "{}/{}/原始图/{}".format(image_dir, goods_art_no_folder, new_file_name)
  626. old_path = "{}/{}/原始图/{}".format(image_dir, goods_art_no_folder, _file)
  627. if old_path != new_path:
  628. # 存在货号命名错误的,进行修正
  629. try:
  630. os.rename(old_path, new_path)
  631. except:
  632. pass
  633. all_original_images.append(new_file_name)
  634. if os.path.exists("{}/{}/原始图/镜像.txt".format(image_dir, goods_art_no_folder)):
  635. file_mirror_mark = True
  636. else:
  637. file_mirror_mark = None
  638. # if goods_art_no_folder == "AC51016112":
  639. # print(file_mirror_mark)
  640. # raise 111
  641. all_moved_images = [os.path.splitext(x)[0] for x in
  642. self.list_dir("{}/{}/原始图_已抠图".format(image_dir, goods_art_no_folder))]
  643. all_800images = [os.path.splitext(x)[0] for x in
  644. self.list_dir(
  645. "{}/{}/800x800".format(image_dir, goods_art_no_folder))]
  646. all_800images = []
  647. # 检查哪些图片没有做过抠图处理
  648. i_n = 0
  649. _name_list = ["视角{}".format(x) for x in range(1, len(all_original_images) + 1)]
  650. # if goods_art_no_folder == "AC51028001":
  651. # _name_list = ["正视", "45度", "侧视", "后视", "底视", "其他1", "其他2", "其他3"]
  652. image_index = 0 # 图片顺序
  653. is_image_deal_mode = 0
  654. max_box = None
  655. for file in all_original_images:
  656. i_n += 1
  657. image_index += 1
  658. original_image_path = "{}/{}/原始图/{}".format(image_dir, goods_art_no_folder, file)
  659. file_name = os.path.splitext(file)[0]
  660. """
  661. 当第三张就是为后跟
  662. """
  663. if file_name not in all_800images: # 所有都重新生成
  664. # if goods_art_no_folder != "AC51016112":
  665. # continue
  666. goods_art_no_folder_path = "{}/{}".format(image_dir, goods_art_no_folder)
  667. print("正在处理,货号:{}".format(goods_art_no_folder_path))
  668. # self.show_progress_detail("正在处理,货号:{}".format(file_name))
  669. callback_func("正在处理,货号:{}".format(file_name))
  670. # 该文件在800images下没有时,则进行生成新的抠图
  671. # 检查是否存在已抠图文件,如没有再去抠图
  672. original_move_bg_image_path = "{}/原始图_已抠图/{}{}".format(goods_art_no_folder_path, file_name,
  673. ".png")
  674. image_deal_mode = 0 # 默认图片不做镜像处理
  675. if not os.path.exists(original_move_bg_image_path):
  676. # 没有抠图文件,进行抠图生成
  677. # self.show_progress_detail("正在抠图 货号:{}".format(file_name))
  678. callback_func("正在抠图 货号:{}".format(file_name))
  679. remove_pic_ins = RemoveBgALi()
  680. im = remove_pic_ins.get_image_cut(file_path=original_image_path,
  681. out_file_path=original_move_bg_image_path)
  682. if not im:
  683. # self.show_progress_detail("货号图{} 抠图处理失败~".format(file_name))
  684. callback_func("货号图{} 抠图处理失败~".format(file_name))
  685. continue
  686. if image_index == 1:
  687. is_image_deal_mode = 0
  688. if settings.Mode == "鞋类":
  689. goods_class = "鞋"
  690. # 如果图片已存在,则需要通过加载图片判断是否为左右脚
  691. if OnePicDeal().check_shoe_is_right(image_path=original_move_bg_image_path):
  692. image_deal_mode = 1 # 1表示要镜像,0表示不做镜像
  693. is_image_deal_mode = 1
  694. if settings.Mode == "皮具":
  695. # 图片对应的商品类型
  696. # goods_class = self.get_goods_class(goods_art_no_folder, original_image_path)
  697. max_box = (1000, 1200)
  698. # _ = {"AC51028001": "女包",
  699. # "AC51028002": "男包",
  700. # "AC51028003": "皮带",
  701. # "AC51028004": "女包"}
  702. # if goods_class in _:
  703. # goods_class = _[goods_class]
  704. # else:
  705. # goods_class = "女包"
  706. #
  707. # _ = {"女包": (1000, 1200),
  708. # "男包": (1000, 1200),
  709. # "皮带": (1000, 1000), }
  710. # max_box = _[goods_class]
  711. # 获取图片信息非必要程序,用于处理图片模式
  712. date_time_original = self.get_date_time_original(original_image_path) # 获取照片拍照时间
  713. if date_time_original:
  714. # 基于照片的时间,与数据库匹配goods_art_no
  715. self.lock.acquire()
  716. _data = self.dataModeMatchPhoto.get_goods_art_no(date_time_original)
  717. self.lock.release()
  718. if _data:
  719. # 能匹配上数据库
  720. goods_art_no, _image_index, _image_deal_mode = _data
  721. if _image_index < 10:
  722. image_index = _image_index
  723. if _image_deal_mode == 1:
  724. image_deal_mode = 1
  725. # print(goods_art_no, image_index, image_deal_mode)
  726. if file_mirror_mark:
  727. image_deal_mode = 1
  728. """进行800image 生成"""
  729. generate_pic = GeneratePic()
  730. out_pci_mode = "." + settings.getSysConfigs(
  731. "basic_configs", "image_out_format", "png"
  732. )
  733. if out_pci_mode == ".jpg":
  734. out_path = "{}/800x800/{}{}".format(goods_art_no_folder_path, file_name, ".jpg")
  735. elif out_pci_mode == ".png":
  736. out_path = "{}/800x800/{}{}".format(goods_art_no_folder_path, file_name, ".png")
  737. else:
  738. out_path = "{}/800x800/{}{}".format(
  739. goods_art_no_folder_path, file_name, out_pci_mode
  740. )
  741. out_process_path_1 = "{}/阴影图处理/{}_{}_阴影{}".format(goods_art_no_folder_path, file_name,
  742. _name_list[i_n - 1], ".png")
  743. out_process_path_2 = "{}/阴影图处理/{}_{}_抠图{}".format(goods_art_no_folder_path, file_name,
  744. _name_list[i_n - 1], ".png")
  745. print("image_index", image_index)
  746. image_index = 99
  747. curve_mask = True if "俯视" in image_order["image_view"] else False
  748. out_pic_size = (
  749. [1600]
  750. if settings.getSysConfigs(
  751. "basic_configs", "main_image_size", [1600]
  752. )
  753. == ""
  754. else settings.getSysConfigs(
  755. "basic_configs", "main_image_size", [1600]
  756. )
  757. ) # 主图大小
  758. if generate_pic.run(image_path=original_image_path,
  759. cut_image_path=original_move_bg_image_path,
  760. out_path=out_path,
  761. image_deal_mode=is_image_deal_mode,
  762. image_index=image_index,
  763. out_pic_size=out_pic_size,
  764. is_logo=True if i_n == 1 else False,
  765. out_process_path_1=out_process_path_1,
  766. out_process_path_2=out_process_path_2,
  767. max_box=max_box,
  768. logo_path=logo_path,
  769. curve_mask=curve_mask
  770. ):
  771. # self.show_progress_detail("货号图{} _{} 已完成800*800图片制作~".format(image_index, file_name))
  772. callback_func("货号图{} _{} 已完成800*800图片制作~".format(image_index, file_name))
  773. else:
  774. # self.show_progress_detail("货号图{} _{} 图片生成处理失败~".format(image_index, file_name))
  775. callback_func("货号图{} _{} 图片生成处理失败~".format(image_index, file_name))
  776. # 完成处理的图片进度
  777. self.lock.acquire()
  778. # self.set_progress()
  779. self.lock.release()
  780. def get_goods_art_no(self, date_time_original):
  781. time_array = time.strptime(date_time_original, "%Y:%m:%d %H:%M:%S")
  782. time_array = time.mktime(time_array)
  783. datetime_obj = datetime.fromtimestamp(time_array)
  784. session = SqlQuery()
  785. configModel = CRUD(DeviceConfig)
  786. result = configModel.read(
  787. session, conditions={"photo_create_time": datetime_obj}, order_by="id", ascending=True
  788. )
  789. if result:
  790. return result.goods_art_no, result.image_index, result.image_deal_mode
  791. else:
  792. return None
  793. def get_goods_art_no_info(self, numbers_list=None, goods_art_list=None, headers=None):
  794. # 获取商品基础信息,入参为商品的编号
  795. url = "{domain}/api/backend/goods_client/goods_query".format(
  796. domain=settings.APP_HOST
  797. )
  798. data = {
  799. 'goods_art_list': goods_art_list
  800. }
  801. data = json.dumps(data)
  802. _s = requests.session().post(url=url, data=data, headers=headers)
  803. response_data = _s.json()
  804. goods_number_data = {}
  805. # ["", "", "", "", "", "", "", "", "", "", "", ]
  806. if "data" not in response_data:
  807. return {}
  808. for data in response_data["data"]:
  809. goods_number_data[data["goods_art_no"]] = {}
  810. goods_number_data[data["goods_art_no"]]["商品货号"] = data["goods_art_no"].upper()
  811. goods_number_data[data["goods_art_no"]]["款号"] = data["goods_number"].upper()
  812. goods_number_data[data["goods_art_no"]]["商品面料"] = data["fabric"]
  813. goods_number_data[data["goods_art_no"]]["商品内里"] = data["lining"]
  814. goods_number_data[data["goods_art_no"]]["商品鞋底"] = data["sole"]
  815. goods_number_data[data["goods_art_no"]]["鞋垫"] = data["insole"]
  816. goods_number_data[data["goods_art_no"]]["颜色名称"] = data["color"]
  817. return goods_number_data
  818. def get_data_from_hqt_with_goods_art_no(self, goods_art_no_list):
  819. _goods_art_no_list = copy.deepcopy(goods_art_no_list)
  820. _list = []
  821. # 单次请求数少于20个
  822. goods_art_no_dict = {}
  823. while _goods_art_no_list:
  824. goods_art_no = _goods_art_no_list.pop()
  825. _list.append(goods_art_no)
  826. if len(_list) == 20 or len(_goods_art_no_list) == 0:
  827. online_goods_art_data = self.get_goods_art_no_info(
  828. goods_art_list=_list
  829. )
  830. if online_goods_art_data:
  831. for _goods_art_no in online_goods_art_data:
  832. goods_art_no_dict[_goods_art_no] = online_goods_art_data[
  833. _goods_art_no
  834. ]
  835. _list = []
  836. return goods_art_no_dict
  837. def get_goods_art_no_info(self, numbers_list=None, goods_art_list=None, headers=None):
  838. # 获取商品基础信息,入参为商品的编号
  839. url = "{domain}/api/backend/goods_client/goods_query".format(
  840. domain=settings.APP_HOST
  841. )
  842. data = {
  843. 'goods_art_list': goods_art_list
  844. }
  845. data = json.dumps(data)
  846. _s = requests.session().post(url=url, data=data, headers=headers)
  847. # _s = self.s.get(url=url, params=params, headers=settings.Headers)
  848. response_data = _s.json()
  849. goods_number_data = {}
  850. # ["", "", "", "", "", "", "", "", "", "", "", ]
  851. if "data" not in response_data:
  852. return {}
  853. for data in response_data["data"]:
  854. goods_number_data[data["goods_art_no"]] = {}
  855. goods_number_data[data["goods_art_no"]]["商品货号"] = data["goods_art_no"].upper()
  856. goods_number_data[data["goods_art_no"]]["款号"] = data["goods_number"].upper()
  857. goods_number_data[data["goods_art_no"]]["商品面料"] = data["fabric"]
  858. goods_number_data[data["goods_art_no"]]["商品内里"] = data["lining"]
  859. goods_number_data[data["goods_art_no"]]["商品鞋底"] = data["sole"]
  860. goods_number_data[data["goods_art_no"]]["鞋垫"] = data["insole"]
  861. goods_number_data[data["goods_art_no"]]["颜色名称"] = data["color"]
  862. return goods_number_data
  863. def get_data_from_hqt(self, goods_number_list):
  864. _goods_number_list = copy.deepcopy(goods_number_list)
  865. _list = []
  866. # 单次请求数少于20个
  867. goods_number_dict = {}
  868. while _goods_number_list:
  869. goods_art_no = _goods_number_list.pop()
  870. if "NUM" in goods_art_no:
  871. goods_art_no = goods_art_no.replace("NUM", "")
  872. _list.append(goods_art_no)
  873. if len(_list) == 20 or len(_goods_number_list) == 0:
  874. online_goods_art_data = self.get_goods_art_no_info(
  875. numbers_list=_list
  876. )
  877. if online_goods_art_data:
  878. for number in online_goods_art_data:
  879. goods_number_dict["NUM" + number] = online_goods_art_data[
  880. number
  881. ]
  882. _list = []
  883. return goods_number_dict
  884. def dealMoveImage(self, image_dir: str, callback_func=None) -> dict:
  885. if not self.check_path(image_dir=image_dir + "/历史"):
  886. return {'code': 1, 'msg': '文件夹创建失败', 'data': {}}
  887. # 遍历目标文件夹,获取有拍摄信息的图片,并按拍摄时间排序
  888. files = self.list_dir(image_dir)
  889. original_photo_list = [] # 原始图片列表
  890. for file in files:
  891. # -----图片清洗
  892. file_path = image_dir + "/" + file
  893. if os.path.isdir(file_path): # 忽略文件夹
  894. continue
  895. file_name, suffix = os.path.splitext(file)
  896. if suffix not in _Type: # 非图片进行移除
  897. shutil.move(file_path, image_dir + "/历史/" + file)
  898. continue
  899. date_time_original = self.get_date_time_original(file_path) # 获取照片拍照时间
  900. if date_time_original:
  901. # 基于照片的时间,与数据库匹配goods_art_no
  902. _data = self.get_goods_art_no(date_time_original)
  903. if _data:
  904. # 能匹配上数据库
  905. goods_art_no, image_index, image_deal_mode = _data
  906. print("832 与数据库匹配goods_art_no", file_name, date_time_original, goods_art_no)
  907. original_photo_list.append({"file_path": file_path,
  908. "file": file,
  909. "date_time_original": date_time_original,
  910. "goods_art_no": goods_art_no,
  911. "image_index": image_index,
  912. "real_goods_art_no": "",
  913. "real_goods_number": "",
  914. })
  915. else:
  916. # 匹配不上报错
  917. # self.show_progress_detail("图片:{} 无法对应货号,不做处理".format(file))
  918. if callback_func:
  919. callback_func("图片:{} 无对应货号".format(file))
  920. # shutil.move(photo_dict["file_path"], self.image_dir + "/历史/" + photo_dict["file"])
  921. continue
  922. else:
  923. shutil.move(file_path, image_dir + "/历史/" + file)
  924. if not original_photo_list:
  925. return {"code": 1, "msg": "没有任何匹配的图片", 'data': {}}
  926. if settings.PROJECT == "红蜻蜓":
  927. # 批量请求货号图信息
  928. goods_art_no_list = [x["goods_art_no"] for x in original_photo_list]
  929. goods_art_no_list = list(set(goods_art_no_list))
  930. goods_art_no_list = [x for x in goods_art_no_list if "NUM" not in x]
  931. if goods_art_no_list:
  932. goods_art_no_dict = self.get_data_from_hqt_with_goods_art_no(
  933. goods_art_no_list=goods_art_no_list)
  934. for i in original_photo_list:
  935. if i["goods_art_no"] in goods_art_no_dict:
  936. i["real_goods_art_no"] = i["goods_art_no"]
  937. i["real_goods_number"] = "NUM{}".format(goods_art_no_dict[i["goods_art_no"]]["编号"])
  938. # 批量请求编号对应信息
  939. goods_number_list = [x["goods_art_no"] for x in original_photo_list]
  940. goods_number_list = list(set(goods_number_list))
  941. goods_number_list = [x for x in goods_number_list if "NUM" in x]
  942. if goods_number_list:
  943. goods_number_dict = self.get_data_from_hqt(goods_number_list=goods_number_list)
  944. for i in original_photo_list:
  945. if i["goods_art_no"] in goods_number_dict:
  946. i["real_goods_number"] = i["goods_art_no"]
  947. i["real_goods_art_no"] = goods_number_dict[i["goods_art_no"]]["商品货号"]
  948. # 排序需要基于拍照的文件序号进行处理
  949. original_photo_list.sort(
  950. key=lambda x: "{}-{}-{}".format(x["goods_art_no"], x["image_index"], x["file"]))
  951. # print(original_photo_list)
  952. # 对有拍摄信息的图片进行数据库比对,如有比对上,则移动至货号文件夹,否则移入历史文件夹
  953. total_num = len(original_photo_list)
  954. # 当天日期作为文件夹
  955. seconds = time.time()
  956. output_path = "output/{f_name}".format(f_name=time.strftime("%Y-%m-%d", time.localtime(seconds)))
  957. # 遍历每个匹配好的数据进行处理
  958. n = 0
  959. for photo_dict in original_photo_list:
  960. n += 1
  961. # 进度条
  962. goods_art_no = photo_dict["goods_art_no"]
  963. original_image_path = photo_dict["file_path"]
  964. # 输出货号文件夹
  965. if photo_dict["real_goods_art_no"]:
  966. goods_art_no = "{}@{}".format(photo_dict["real_goods_art_no"], photo_dict["real_goods_number"])
  967. goods_art_no_path = "{output_path}/{goods_art_no}".format(output_path=output_path,
  968. goods_art_no=goods_art_no)
  969. # 创建货号下的一系列文件夹
  970. self.create_folder(goods_art_no_path)
  971. # 重命名并进行移动
  972. print("开始移动:{} {} 命名为:{}".format(goods_art_no, original_image_path, goods_art_no_path))
  973. self.move_images(goods_art_no, goods_art_no_path, original_image_path) # 货号、货号文件路径、原始图路径
  974. time.sleep(0.2)
  975. # self.progress_sign.emit({"type": "移动原始图片", "progress_bar_value": int(n / total_num * 100)})
  976. # self.show_progress_detail("货号{} 相关文件夹创建完成,已移动原图~".format(goods_art_no))
  977. if callback_func:
  978. callback_func("货号{} 相关文件夹创建完成,已移动原图~".format(goods_art_no))
  979. print("已完成移动处理")
  980. if n != 0:
  981. # if settings.MattingPics:
  982. # # 检查所有未处理的货号文件夹,查看是否有完成图片加工处理
  983. # self.deal_images()
  984. # 自动生成一个货号表
  985. print("output_path", output_path)
  986. GenerateGoodsArtNoTable.deal(output_path)
  987. # 完成处理
  988. # self.set_state(state_value=2)
  989. return {'code': 0, 'msg': '处理完成', 'target_path': output_path, 'data': {}}
  990. def check_path(self, image_dir: str):
  991. if not os.path.exists(image_dir):
  992. os.mkdir(image_dir)
  993. return True
  994. def get_date_time_original(self, file_path):
  995. with open(file_path, 'rb') as file_data:
  996. tags = exifread.process_file(file_data)
  997. if "EXIF DateTimeOriginal" in tags:
  998. return str(tags["EXIF DateTimeOriginal"])
  999. else:
  1000. return False
  1001. def create_folder(self, path):
  1002. def check_folder(__path):
  1003. if not os.path.exists(__path):
  1004. os.makedirs(__path)
  1005. return False
  1006. return True
  1007. # 文件夹不存在,创建货号子集文件夹
  1008. if not check_folder(path):
  1009. for name in ["原始图", "原始图_已抠图", "800x800", "200images"]:
  1010. other_path = path + "/" + name
  1011. check_folder(other_path)
  1012. def move_images(self, goods_art_no, goods_art_no_path, old_image_path):
  1013. """
  1014. 步骤:
  1015. 1、移动到原始图
  1016. Args:
  1017. goods_art_no:
  1018. goods_art_no_path:
  1019. old_image_path:
  1020. Returns:
  1021. """
  1022. # 移动到原始图
  1023. file = os.path.split(old_image_path)[1]
  1024. # 扩展名
  1025. e = os.path.splitext(file)[1]
  1026. # 获取图片序列
  1027. self.goods_images_count_dict[goods_art_no] += 1
  1028. # A9999(1).jpg
  1029. new_file_name = "{}({})".format(goods_art_no, self.goods_images_count_dict[goods_art_no])
  1030. original_image_path = "{}/原始图/{}{}".format(goods_art_no_path, new_file_name, e)
  1031. # 移动图片
  1032. shutil.move(old_image_path, original_image_path)
  1033. def pixianRemoveImageBg(self, file_path: str, out_file_path: str, callbackek_func=None):
  1034. url = self.dataModeMatchPhoto.get_online_data.uploadImage(local_path=file_path)
  1035. remonveUrl = settings.DOMAIN + '/api/ai_image/main/remove_background'
  1036. param = {'base_image': url}
  1037. post_headers = {"Authorization": self.token,
  1038. "Content-Length": "",
  1039. "Content-Type": "application/json",
  1040. "Accept": "application/json"}
  1041. result = requests.post(remonveUrl, data=json.dumps(param), headers=post_headers).json()
  1042. print(result)
  1043. if "code" in result and result['code'] == 0:
  1044. response = requests.get(result['data']['image'][0])
  1045. with open(out_file_path, 'wb') as file:
  1046. file.write(response.content)
  1047. return result['data']['image'][0]
  1048. else:
  1049. callbackek_func("精细化抠图处理失败 {}".format(result['message']))
  1050. return ''
  1051. def list_dir(self, path):
  1052. listdir = os.listdir(path)
  1053. return natsorted(listdir, alg=ns.PATH)