base_deal.py 56 KB

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