module_rename_pic.py 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. from UI.rename_pic import Ui_Form as rename_pic_Ui_Form
  2. from PySide6.QtWidgets import *
  3. from PySide6.QtCore import *
  4. # from collections import defaultdict
  5. import os
  6. import log
  7. from PIL import Image, ImageDraw, ImageFont
  8. import time
  9. import settings
  10. # from pyzbar.pyzbar import decode
  11. import shutil
  12. from cv2 import cvtColor, COLOR_RGB2BGR
  13. # cv2.cvtColor(np.asarray(im), cv2.COLOR_RGB2BGR)
  14. import numpy as np
  15. from cv2.wechat_qrcode import WeChatQRCode
  16. from module.module_online_data import GetOnlineData
  17. from MineQWidget import MineQWidget
  18. # pip install opencv-python -i https://pypi.douban.com/simple
  19. # pip install opencv-contrib-python -i https://pypi.douban.com/simple
  20. class Picture:
  21. def __init__(self, in_path):
  22. self.im = Image.open(in_path)
  23. self.x, self.y = self.im.size
  24. # print(self.x, self.y)
  25. def save_img(self, outpath, quality=90):
  26. # self.im = self.im.convert("RGB")
  27. self.im.save(outpath, quality=quality)
  28. def resize(self, width):
  29. re_x = int(width)
  30. re_y = int(self.y * re_x / self.x)
  31. self.im = self.im.resize((re_x, re_y), Image.Resampling.LANCZOS)
  32. self.x, self.y = self.im.size
  33. def resize_regular(self, width, high):
  34. self.im = self.im.resize((width, high), Image.Resampling.LANCZOS)
  35. def corp_square(self):
  36. if self.y < self.x:
  37. return
  38. self.im = self.im.crop(
  39. (0, int((self.y - self.x) / 2), self.x, self.y - int((self.y - self.x) / 2))
  40. )
  41. class RenamePic(MineQWidget, rename_pic_Ui_Form):
  42. progress_sign = Signal(dict)
  43. info_sign = Signal(str)
  44. text_show = Signal(str)
  45. def __init__(self, windows=None):
  46. super().__init__()
  47. # 加载默认配置
  48. self.setupUi(self)
  49. # 0禁用 1进行中 2已结束
  50. self.state = 2
  51. self.init()
  52. self.pic_dir = ""
  53. self.setFixedSize(self.width(), self.height())
  54. self.set_state(2)
  55. self.show()
  56. QTimer.singleShot(500, self.checkLogin)
  57. def init(self):
  58. self.text_show.connect(self.append_text_to_browser)
  59. self.label_3.mousePressEvent = self.select_pic_dir
  60. self.label_4.setText("")
  61. # self.label_6.setText(self.get_len_text(self.to_deal_excel_dir, 50))
  62. self.pushButton.clicked.connect(self.run)
  63. def create_folder(self, path):
  64. if not os.path.exists(path):
  65. os.makedirs(path)
  66. def get_len_text(self, text, max_len: int):
  67. if len(text) > max_len:
  68. text = text[: int(max_len / 4)] + "..." + text[-1 * int(max_len * 3 / 4) :]
  69. return text
  70. def select_pic_dir(self, *args):
  71. pic_dir = QFileDialog.getExistingDirectory(None, "选取文件夹", "")
  72. if not pic_dir:
  73. self.label_4.setText("")
  74. return
  75. self.pic_dir = pic_dir
  76. self.label_4.setText(pic_dir)
  77. def check_path(self, _path):
  78. if not os.path.exists(_path):
  79. os.mkdir(_path)
  80. return True
  81. def set_state(self, state_value: int):
  82. # 0禁用 1进行中 2已结束
  83. if state_value not in [0, 1, 2]:
  84. return
  85. self.state = state_value
  86. if self.state == 0:
  87. self.progressBar.hide()
  88. self.pushButton.setEnabled(False)
  89. if self.state == 1:
  90. self.progressBar.show()
  91. self.progressBar.setValue(0)
  92. self.textBrowser_2.show()
  93. self.pushButton.setEnabled(False)
  94. self.textBrowser_2.clear()
  95. if self.state == 2:
  96. self.progressBar.hide()
  97. self.pushButton.setEnabled(True)
  98. def run(self):
  99. # 基础检查
  100. checkRes = self.checkLogin()
  101. if checkRes == False:
  102. return
  103. self.set_state(1)
  104. if not self.pic_dir:
  105. self.text_show.emit("请选择图片文件夹")
  106. self.set_state(2)
  107. return
  108. if self.comboBox.currentText() == "请选择":
  109. self.text_show.emit("请选择是否将货号添加到图片中")
  110. self.set_state(2)
  111. return
  112. total = 0
  113. _Type = [".png", ".PNG", ".jpg", ".JPG", ".gif", ".GIF", ".jpeg", ".JPEG"]
  114. for image_file in os.listdir(self.pic_dir):
  115. path = "{}\{}".format(self.pic_dir, image_file)
  116. if os.path.isfile(path):
  117. if os.path.splitext(image_file)[1] in _Type:
  118. total += 1
  119. if total == 0:
  120. self.text_show.emit("当前文件夹下没有图片")
  121. self.set_state(2)
  122. return
  123. is_add_text = False
  124. if self.comboBox.currentText() == "添加":
  125. is_add_text = True
  126. self.run_deal(total=total, is_add_text=is_add_text)
  127. self.set_state(2)
  128. def send_info(self, data):
  129. if data["_type"] == "show_p":
  130. self.progressBar.setValue(data["data"])
  131. if data["_type"] == "text":
  132. self.textBrowser_2.append(data["data"])
  133. def run_deal(self, total, is_add_text=False):
  134. # 输出目录
  135. out_put_path = "{}\out_put_{}".format(
  136. os.path.split(self.pic_dir)[0], int(time.time())
  137. )
  138. # 无法识别的目录
  139. error_path = "{}\识别失败".format(out_put_path)
  140. # 识别成功的目录
  141. success_path = "{}\识别成功".format(out_put_path)
  142. self.check_path(out_put_path)
  143. self.check_path(error_path)
  144. self.check_path(success_path)
  145. error_list = []
  146. _Type = [".png", ".PNG", ".jpg", ".JPG", ".gif", ".GIF", ".jpeg", ".JPEG"]
  147. last_code = None
  148. do_n = 0
  149. for image_file in os.listdir(self.pic_dir):
  150. if os.path.splitext(image_file)[1] in _Type:
  151. # 获取当前路径的文件夹名称
  152. file_path = "{}/{}".format(self.pic_dir, image_file)
  153. self.send_info(
  154. {"_type": "text", "data": "{}图片解析".format(image_file)}
  155. )
  156. code = self.get_code(file_path)
  157. if code:
  158. if "_" in code:
  159. goods_number = code.split("_")[0]
  160. numbers_list = [goods_number]
  161. r_data = GetOnlineData().get_goods_art_no_info(
  162. numbers_list=numbers_list
  163. )
  164. if goods_number in r_data:
  165. code = r_data[goods_number]["商品货号"]
  166. else:
  167. code = None
  168. self.send_info(
  169. {
  170. "_type": "text",
  171. "data": "{}查询不到商品".format(goods_number),
  172. }
  173. )
  174. if code:
  175. # 获取到二维码内容,说明是二维码图片,则不做处理
  176. last_code = code
  177. continue
  178. else:
  179. # 上个二维码没有解析成功
  180. if not last_code:
  181. error_list.append(image_file)
  182. self.send_info(
  183. {"_type": "text", "data": "{}无法识别".format(image_file)}
  184. )
  185. shutil.copyfile(
  186. file_path, "{}\{}".format(error_path, image_file)
  187. )
  188. #
  189. if last_code:
  190. print("{}--------".format(last_code))
  191. # 目标文件路径
  192. _file_name = "{}{}".format(
  193. last_code, os.path.splitext(image_file)[1]
  194. )
  195. dst_file = "{}/{}".format(success_path, _file_name)
  196. if os.path.exists(dst_file):
  197. self.send_info(
  198. {
  199. "_type": "text",
  200. "data": "{}图片已存在".format(image_file),
  201. }
  202. )
  203. last_code = None
  204. continue
  205. shutil.copy(file_path, dst_file) # 复制文件
  206. pic = Picture(dst_file)
  207. pic.resize(width=800)
  208. pic.corp_square() # 居中剪裁
  209. if is_add_text:
  210. draw = ImageDraw.Draw(pic.im)
  211. font_style_1 = ImageFont.truetype(
  212. r"ttf\simfang.ttf", 40, encoding="utf-8"
  213. )
  214. draw.text((0, 0), last_code, 0, font=font_style_1)
  215. pic.save_img(dst_file)
  216. # 处理成功了,清空上个记录
  217. last_code = None
  218. do_n += 1
  219. self.send_info({"_type": "show_p", "data": int(do_n / total * 100)})
  220. if error_list:
  221. self.send_info({"_type": "text", "data": "以下图片无法解析,请自行处理"})
  222. self.send_info({"_type": "text", "data": "{}".format(error_list)})
  223. os.startfile(out_put_path)
  224. def append_text_to_browser(self, text):
  225. self.textBrowser_2.append(text)
  226. def create_folder(self, path):
  227. if not os.path.exists(path):
  228. os.makedirs(path)
  229. return False
  230. def get_code(self, file_path):
  231. pic = Picture(file_path)
  232. pic.resize(width=1000)
  233. im = pic.im
  234. img = cvtColor(np.asarray(im), COLOR_RGB2BGR)
  235. # path = r"D:\MyDocuments\PythonCode\MyPython\red_dragonfly\deal_pics\rename_by_qrcode\opencv_3rdparty-wechat_qrcode"
  236. detector = WeChatQRCode(
  237. detector_prototxt_path="qr_mode/detect.prototxt",
  238. detector_caffe_model_path="qr_mode/detect.caffemodel",
  239. super_resolution_prototxt_path="qr_mode/sr.prototxt",
  240. super_resolution_caffe_model_path="qr_mode/sr.caffemodel",
  241. )
  242. res, points = detector.detectAndDecode(img)
  243. if res:
  244. return res[0]
  245. return None
  246. def deal_pic_resize(
  247. self,
  248. file_path,
  249. target_size,
  250. times=0,
  251. ):
  252. file_size = int(os.path.getsize(file_path) / 1024)
  253. if file_size < target_size:
  254. return
  255. times += 1
  256. if times > 2:
  257. print(file_path, "压缩次数", times)
  258. k = 0.9
  259. # if file_size > target_size * 5:
  260. # k = 0.7
  261. pic = Picture(file_path)
  262. w = int(pic.x * k)
  263. pic.resize(w)
  264. pic.save_img(file_path)
  265. return self.deal_pic_resize(file_path, target_size, times)