grenerate_main_image_test.py 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623
  1. import os
  2. import copy
  3. import time
  4. from generate_main_image.image_deal_base_func import *
  5. from PIL import Image, ImageDraw
  6. from blend_modes import multiply
  7. import os
  8. import settings
  9. from functools import wraps
  10. from multi_threaded_image_saving import ImageSaver
  11. from get_mask_by_green import GetMask
  12. #
  13. def time_it(func):
  14. @wraps(func) # 使用wraps来保留原始函数的元数据信息
  15. def wrapper(*args, **kwargs):
  16. start_time = time.time() # 记录开始时间
  17. result = func(*args, **kwargs) # 调用原始函数
  18. end_time = time.time() # 记录结束时间
  19. print(
  20. f"Executing {func.__name__} took {end_time - start_time:.4f} seconds."
  21. ) # 打印耗时
  22. return result
  23. return wrapper
  24. class GeneratePic(object):
  25. def __init__(self, is_test=False):
  26. # self.logger = MyLogger()
  27. self.is_test = is_test
  28. self.saver = ImageSaver()
  29. pass
  30. @time_it
  31. def get_mask_and_config(self, im_jpg: Image, im_png: Image, curve_mask: bool):
  32. """
  33. 步骤:
  34. 1、尺寸进行对应缩小
  35. 2、查找并设定鞋底阴影蒙版
  36. 3、自动色阶检查亮度
  37. 4、输出自动色阶参数、以及放大的尺寸蒙版
  38. """
  39. # ===================尺寸进行对应缩小(提升处理速度)
  40. im_jpg = to_resize(im_jpg, width=800)
  41. im_png = to_resize(im_png, width=800)
  42. x1, y1, x2, y2 = im_png.getbbox()
  43. cv2_png = pil_to_cv2(im_png)
  44. # =====================设定鞋底阴影图的蒙版
  45. # 查找每列的最低非透明点
  46. min_y_values = find_lowest_non_transparent_points(cv2_png)
  47. # 在鞋底最低处增加一条直线蒙版,蒙版宽度为有效区域大小
  48. image_high = im_jpg.height
  49. print("图片高度:", image_high)
  50. # TODO 待移除
  51. if settings.app:
  52. settings.app.processEvents()
  53. cv2_jpg = pil_to_cv2(im_jpg)
  54. # 返回线条图片,以及最低位置
  55. print("返回线条图片,以及最低位置")
  56. # crop_image_box=(x1, y1, x2, y2),
  57. if curve_mask:
  58. crop_image_box = None
  59. else:
  60. # 不需要曲线部分的蒙版
  61. crop_image_box = (x1, y1, x2, y2)
  62. img_with_shifted_line, lowest_y = draw_shifted_line(
  63. image=cv2_jpg,
  64. min_y_values=min_y_values,
  65. shift_amount=15,
  66. one_line_pos=(x1, x2),
  67. line_color=(0, 0, 0),
  68. line_thickness=20,
  69. app=settings.app,
  70. crop_image_box=crop_image_box,
  71. )
  72. # TODO 待移除
  73. if settings.app:
  74. settings.app.processEvents()
  75. print("66 制作蒙版")
  76. # 制作蒙版
  77. mask_line = cv2_to_pil(img_with_shifted_line)
  78. mask = mask_line.convert("L") # 转换为灰度图
  79. mask = ImageOps.invert(mask)
  80. # 蒙版扩边
  81. print("72 蒙版扩边")
  82. # 默认expansion_radius 65 blur_radius 45
  83. mask = expand_or_shrink_mask(
  84. pil_image=mask, expansion_radius=50, blur_radius=35
  85. )
  86. # =============使用绿色蒙版进行处理
  87. if settings.IS_GET_GREEN_MASK:
  88. print("============使用绿色蒙版进行处理")
  89. mask = mask.convert("RGB")
  90. white_bg = Image.new(mode="RGB", size=im_png.size, color=(0, 0, 0))
  91. green_areas_mask_pil = GetMask().find_green_areas(cv2_jpg)
  92. green_areas_mask_pil = expand_or_shrink_mask(
  93. pil_image=green_areas_mask_pil, expansion_radius=15, blur_radius=5
  94. )
  95. mask.paste(white_bg, mask=green_areas_mask_pil.convert("L"))
  96. mask = mask.convert("L")
  97. # TODO 待移除
  98. if settings.app:
  99. settings.app.processEvents()
  100. # ====================生成新的图片
  101. print("84 生成新的图片")
  102. bg = Image.new(mode="RGBA", size=im_png.size, color=(255, 255, 255, 255))
  103. bg.paste(im_png, mask=im_png)
  104. bg.paste(im_jpg, mask=mask) # 粘贴有阴影的地方
  105. # TODO 待移除
  106. if settings.app:
  107. settings.app.processEvents()
  108. if self.is_test:
  109. _bg = bg.copy()
  110. draw = ImageDraw.Draw(_bg)
  111. # 定义直线的起点和终点坐标
  112. start_point = (0, lowest_y) # 直线的起始点
  113. end_point = (_bg.width, lowest_y) # 直线的结束点
  114. # 定义直线的颜色(R, G, B)
  115. line_color = (255, 0, 0) # 红色
  116. _r = Image.new(mode="RGBA", size=im_png.size, color=(246, 147, 100, 255))
  117. # mask_line = mask_line.convert('L') # 转换为灰度图
  118. # mask_line = ImageOps.invert(mask_line)
  119. # _bg.paste(_r, mask=mask)
  120. # 绘制直线
  121. draw.line([start_point, end_point], fill=line_color, width=1)
  122. _bg.show()
  123. # bg.save(r"C:\Users\gymmc\Desktop\data\bg.png")
  124. # bg.show()
  125. # ==================自动色阶处理======================
  126. # 对上述拼接后的图片进行自动色阶处理
  127. bg = bg.convert("RGB")
  128. _im = cv2.cvtColor(np.asarray(bg), cv2.COLOR_RGB2BGR)
  129. # 背景阴影
  130. im_shadow = cv2.cvtColor(_im, cv2.COLOR_BGR2GRAY)
  131. print("image_high lowest_y", image_high, lowest_y)
  132. if lowest_y < 0 or lowest_y >= image_high:
  133. lowest_y = image_high - 1
  134. print("image_high lowest_y", image_high, lowest_y)
  135. rows = [lowest_y] # 需要检查的像素行
  136. print("copy.copy(im_shadow)")
  137. _im_shadow = copy.copy(im_shadow)
  138. Midtones = 0.7
  139. Highlight = 235
  140. k = copy.copy(settings.COLOR_GRADATION_CYCLES)
  141. print("循环识别")
  142. xunhuan = 0
  143. while k:
  144. xunhuan += 1
  145. if settings.app:
  146. settings.app.processEvents()
  147. k -= 1
  148. Midtones += 0.035
  149. if Midtones > 1.7:
  150. Midtones = 1.7
  151. Highlight -= 3
  152. _im_shadow = levels_adjust(
  153. img=im_shadow,
  154. Shadow=0,
  155. Midtones=Midtones,
  156. Highlight=Highlight,
  157. OutShadow=0,
  158. OutHighlight=255,
  159. Dim=3,
  160. )
  161. brightness_list = calculate_average_brightness_opencv(
  162. img_gray=_im_shadow, rows_to_check=rows
  163. )
  164. print(
  165. "循环识别:{},Midtones:{},Highlight:{},brightness_list:{}".format(
  166. xunhuan, Midtones, Highlight, brightness_list
  167. )
  168. )
  169. if brightness_list[0] >= settings.GRENERATE_MAIN_PIC_BRIGHTNESS:
  170. break
  171. im_shadow = cv2_to_pil(_im_shadow)
  172. # ========================================================
  173. # 计算阴影的亮度,用于确保阴影不要太黑
  174. # 1、图片预处理,只保留阴影
  175. only_shadow_img = im_shadow.copy()
  176. only_shadow_img.paste(
  177. Image.new(
  178. mode="RGBA", size=only_shadow_img.size, color=(255, 255, 255, 255)
  179. ),
  180. mask=im_png,
  181. )
  182. average_brightness = calculated_shadow_brightness(only_shadow_img)
  183. print("average_brightness:", average_brightness)
  184. config = {
  185. "Midtones": Midtones,
  186. "Highlight": Highlight,
  187. "average_brightness": average_brightness,
  188. }
  189. return mask, config
  190. def get_mask_and_config_1_2025_05_18(self, im_jpg: Image, im_png: Image):
  191. """
  192. 步骤:
  193. 1、尺寸进行对应缩小
  194. 2、查找并设定鞋底阴影蒙版
  195. 3、自动色阶检查亮度
  196. 4、输出自动色阶参数、以及放大的尺寸蒙版
  197. """
  198. # ===================尺寸进行对应缩小(提升处理速度)
  199. im_jpg = to_resize(im_jpg, width=800)
  200. im_png = to_resize(im_png, width=800)
  201. x1, y1, x2, y2 = im_png.getbbox()
  202. cv2_png = pil_to_cv2(im_png)
  203. # =====================设定鞋底阴影图的蒙版
  204. # 查找每列的最低非透明点
  205. min_y_values = find_lowest_non_transparent_points(cv2_png)
  206. # 在鞋底最低处增加一条直线蒙版,蒙版宽度为有效区域大小
  207. image_high = im_jpg.height
  208. print("图片高度:", image_high)
  209. # TODO 待移除
  210. if settings.app:
  211. settings.app.processEvents()
  212. cv2_jpg = pil_to_cv2(im_jpg)
  213. # 返回线条图片,以及最低位置
  214. print("返回线条图片,以及最低位置")
  215. img_with_shifted_line, lowest_y = draw_shifted_line(
  216. image=cv2_jpg,
  217. min_y_values=min_y_values,
  218. shift_amount=15,
  219. one_line_pos=(x1, x2),
  220. line_color=(0, 0, 0),
  221. line_thickness=20,
  222. app=settings.app,
  223. crop_image_box=(x1, y1, x2, y2),
  224. )
  225. # TODO 待移除
  226. if settings.app:
  227. settings.app.processEvents()
  228. print("66 制作蒙版")
  229. # 制作蒙版
  230. mask_line = cv2_to_pil(img_with_shifted_line)
  231. mask = mask_line.convert("L") # 转换为灰度图
  232. mask = ImageOps.invert(mask)
  233. # 蒙版扩边
  234. print("72 蒙版扩边")
  235. # 默认expansion_radius 65 blur_radius 45
  236. mask = expand_or_shrink_mask(
  237. pil_image=mask, expansion_radius=50, blur_radius=35
  238. )
  239. # mask1 = expand_mask(mask, expansion_radius=30, blur_radius=10)
  240. # mask1.save("mask1.png")
  241. # mask2 = expand_or_shrink_mask(pil_image=mask, expansion_radius=60, blur_radius=30)
  242. # mask2.save("mask2.png")
  243. # raise 11
  244. # TODO 待移除
  245. if settings.app:
  246. settings.app.processEvents()
  247. # ====================生成新的图片
  248. print("84 生成新的图片")
  249. bg = Image.new(mode="RGBA", size=im_png.size, color=(255, 255, 255, 255))
  250. bg.paste(im_png, mask=im_png)
  251. bg.paste(im_jpg, mask=mask) # 粘贴有阴影的地方
  252. # TODO 待移除
  253. if settings.app:
  254. settings.app.processEvents()
  255. if self.is_test:
  256. _bg = bg.copy()
  257. draw = ImageDraw.Draw(_bg)
  258. # 定义直线的起点和终点坐标
  259. start_point = (0, lowest_y) # 直线的起始点
  260. end_point = (_bg.width, lowest_y) # 直线的结束点
  261. # 定义直线的颜色(R, G, B)
  262. line_color = (255, 0, 0) # 红色
  263. # 绘制直线
  264. draw.line([start_point, end_point], fill=line_color, width=1)
  265. # mask.show()
  266. # bg = pil_to_cv2(bg)
  267. # cv2.line(bg, (x1, lowest_y + 5), (x2, lowest_y + 5), color=(0, 0, 0),thickness=2)
  268. # bg = cv2_to_pil(bg)
  269. _r = Image.new(mode="RGBA", size=im_png.size, color=(246, 147, 100, 255))
  270. mask_line = mask_line.convert("L") # 转换为灰度图
  271. mask_line = ImageOps.invert(mask_line)
  272. _bg.paste(_r, mask=mask)
  273. _bg.show()
  274. # bg.save(r"C:\Users\gymmc\Desktop\data\bg.png")
  275. # bg.show()
  276. # ==================自动色阶处理======================
  277. # 对上述拼接后的图片进行自动色阶处理
  278. bg = bg.convert("RGB")
  279. _im = cv2.cvtColor(np.asarray(bg), cv2.COLOR_RGB2BGR)
  280. # 背景阴影
  281. im_shadow = cv2.cvtColor(_im, cv2.COLOR_BGR2GRAY)
  282. print("image_high lowest_y", image_high, lowest_y)
  283. if lowest_y < 0 or lowest_y >= image_high:
  284. lowest_y = image_high - 1
  285. print("image_high lowest_y", image_high, lowest_y)
  286. rows = [lowest_y] # 需要检查的像素行
  287. print("copy.copy(im_shadow)")
  288. _im_shadow = copy.copy(im_shadow)
  289. Midtones = 0.7
  290. Highlight = 235
  291. k = 12
  292. print("循环识别")
  293. while k:
  294. print("循环识别:{}".format(k))
  295. if settings.app:
  296. settings.app.processEvents()
  297. k -= 1
  298. Midtones += 0.1
  299. if Midtones > 1:
  300. Midtones = 1
  301. Highlight -= 3
  302. _im_shadow = levels_adjust(
  303. img=im_shadow,
  304. Shadow=0,
  305. Midtones=Midtones,
  306. Highlight=Highlight,
  307. OutShadow=0,
  308. OutHighlight=255,
  309. Dim=3,
  310. )
  311. brightness_list = calculate_average_brightness_opencv(
  312. img_gray=_im_shadow, rows_to_check=rows
  313. )
  314. print(brightness_list)
  315. if brightness_list[0] >= settings.GRENERATE_MAIN_PIC_BRIGHTNESS:
  316. break
  317. print("Midtones,Highlight:", Midtones, Highlight)
  318. im_shadow = cv2_to_pil(_im_shadow)
  319. # ========================================================
  320. # 计算阴影的亮度,用于确保阴影不要太黑
  321. # 1、图片预处理,只保留阴影
  322. only_shadow_img = im_shadow.copy()
  323. only_shadow_img.paste(
  324. Image.new(
  325. mode="RGBA", size=only_shadow_img.size, color=(255, 255, 255, 255)
  326. ),
  327. mask=im_png,
  328. )
  329. average_brightness = calculated_shadow_brightness(only_shadow_img)
  330. print("average_brightness:", average_brightness)
  331. config = {
  332. "Midtones": Midtones,
  333. "Highlight": Highlight,
  334. "average_brightness": average_brightness,
  335. }
  336. return mask, config
  337. def my_test(self, **kwargs):
  338. if "output_queue" in kwargs:
  339. output_queue = kwargs["output_queue"]
  340. else:
  341. output_queue = None
  342. time.sleep(3)
  343. if output_queue is not None:
  344. output_queue.put(True)
  345. @time_it
  346. def run(
  347. self,
  348. image_path,
  349. cut_image_path,
  350. out_path,
  351. image_deal_mode=0,
  352. image_index=99,
  353. out_pic_size=1024,
  354. is_logo=True,
  355. out_process_path_1=None,
  356. out_process_path_2=None,
  357. resize_mode=None,
  358. max_box=None,
  359. logo_path="",
  360. curve_mask=False,
  361. **kwargs,
  362. ): # im 为cv对象
  363. """
  364. image_path:原始图
  365. cut_image_path:抠图结果 与原始图尺寸相同
  366. out_path:输出主图路径
  367. image_deal_mode:图片处理模式,1表示需要镜像处理
  368. image_index:图片顺序索引
  369. out_pic_size:输出图片宽度大小
  370. is_logo=True 是否要添加logo水印
  371. out_process_path_1=None, 有阴影的图片,白底非透明
  372. out_process_path_2=None, 已抠图的图片
  373. resize_mode=0,1,2 主体缩小尺寸
  374. curve_mask 为True时,表示为对鞋曲线部分的mask,不做剪裁
  375. """
  376. if "output_queue" in kwargs:
  377. output_queue = kwargs["output_queue"]
  378. else:
  379. output_queue = None
  380. # ==========先进行剪切原图
  381. _s = time.time()
  382. orign_im = Image.open(image_path) # 原始图
  383. print("242 need_time_1:{}".format(time.time() - _s))
  384. orign_x, orign_y = orign_im.size
  385. cut_image = Image.open(cut_image_path) # 原始图的已扣图
  386. cut_image, new_box = get_mini_crop_img(img=cut_image)
  387. im_shadow = orign_im.crop(new_box) # 切图
  388. new_x, new_y = im_shadow.size
  389. # ================自动色阶处理
  390. _s = time.time()
  391. shadow_mask, config = self.get_mask_and_config(
  392. im_jpg=im_shadow, im_png=cut_image, curve_mask=curve_mask
  393. )
  394. print("242 need_time_2:{}".format(time.time() - _s))
  395. shadow_mask = shadow_mask.resize(im_shadow.size)
  396. # =====抠图,形成新的阴影背景图=====
  397. # TODO 待移除
  398. # settings.app.processEvents()
  399. _new_im_shadow = Image.new(
  400. mode="RGBA", size=im_shadow.size, color=(255, 255, 255, 255)
  401. )
  402. _new_im_shadow.paste(im_shadow, mask=shadow_mask) # 粘贴有阴影的地方
  403. # _new_im_shadow.show()
  404. _new_im_shadow = pil_to_cv2(_new_im_shadow)
  405. _new_im_shadow = cv2.cvtColor(_new_im_shadow, cv2.COLOR_BGR2GRAY)
  406. _new_im_shadow = levels_adjust(
  407. img=_new_im_shadow,
  408. Shadow=0,
  409. Midtones=config["Midtones"],
  410. Highlight=config["Highlight"],
  411. OutShadow=0,
  412. OutHighlight=255,
  413. Dim=3,
  414. )
  415. im_shadow = cv2_to_pil(_new_im_shadow)
  416. # ================处理阴影的亮度==================
  417. average_brightness = config["average_brightness"]
  418. if config["average_brightness"] < 180:
  419. # 调整阴影亮度
  420. backdrop_prepped = np.asfarray(
  421. Image.new(mode="RGBA", size=im_shadow.size, color=(255, 255, 255, 255))
  422. )
  423. im_shadow = im_shadow.convert("RGBA")
  424. source_prepped = np.asfarray(im_shadow)
  425. # im_shadow.show()
  426. opacity = (average_brightness - 30) / 160
  427. opacity = max(0.5, min(opacity, 1))
  428. print("阴影透明度:{}%".format(int(opacity * 100)))
  429. blended_np = multiply(
  430. backdrop_prepped, source_prepped, opacity=int(opacity * 100) / 100
  431. )
  432. im_shadow = Image.fromarray(np.uint8(blended_np)).convert("RGB")
  433. # im_shadow.show()
  434. # 把原图粘贴回去,避免色差
  435. im_shadow.paste(cut_image, (0, 0), mask=cut_image)
  436. # _new_im_shadow.show()
  437. # ===========处理其他====================
  438. # 保存带有阴影的底图,没有logo
  439. if out_process_path_1:
  440. out_image_1 = im_shadow.copy()
  441. if image_deal_mode == 1:
  442. out_image_1 = out_image_1.transpose(Image.FLIP_LEFT_RIGHT)
  443. self.saver.save_image(
  444. image=out_image_1, file_path=out_process_path_1, save_mode="png"
  445. )
  446. # save_image_by_thread(image=out_image_1, out_path=out_process_path_1)
  447. # out_image_1.save(out_process_path_1)
  448. # 保存抠图结果,没有底图,没有logo
  449. if out_process_path_2:
  450. out_image_2 = cut_image.copy()
  451. if image_deal_mode == 1:
  452. out_image_2 = out_image_2.transpose(Image.FLIP_LEFT_RIGHT)
  453. self.saver.save_image(
  454. image=out_image_2, file_path=out_process_path_2, save_mode="png"
  455. )
  456. # save_image_by_thread(image=out_image_2, out_path=out_process_path_2, save_mode="png")
  457. # out_image_2.save(out_process_path_2)
  458. # 不生成主图时直接退出
  459. if not out_path:
  460. return True
  461. # im_shadow.show()
  462. # =====================主图物体的缩放依据大小
  463. if max_box:
  464. im_shadow = to_resize(_im=im_shadow, width=max_box[0], high=max_box[1])
  465. cut_image = to_resize(_im=cut_image, width=max_box[0], high=max_box[1])
  466. else:
  467. if resize_mode is None:
  468. im_shadow = to_resize(_im=im_shadow, width=1400, high=1400)
  469. cut_image = to_resize(_im=cut_image, width=1400, high=1400)
  470. elif resize_mode == 1:
  471. im_shadow = to_resize(_im=im_shadow, width=1400, high=1400)
  472. cut_image = to_resize(_im=cut_image, width=1400, high=1400)
  473. elif resize_mode == 2:
  474. # todo 兼容长筒靴等,将图片大小限制在一个指定的box内
  475. im_shadow = to_resize(_im=im_shadow, width=650)
  476. cut_image = to_resize(_im=cut_image, width=650)
  477. # 再次检查需要约束缩小到一定高度,适应长筒靴
  478. _im_x, _im_y = cut_image.size
  479. if _im_y > 1400:
  480. im_shadow = to_resize(_im=im_shadow, high=1400)
  481. cut_image = to_resize(_im=cut_image, high=1400)
  482. # if im_shadow.height <= im_shadow.width * 1.2:
  483. # im_shadow = to_resize(_im=im_shadow, width=650)
  484. # cut_image = to_resize(_im=cut_image, width=650)
  485. # else:
  486. # im_shadow = to_resize(_im=im_shadow, high=1400)
  487. # cut_image = to_resize(_im=cut_image, high=1400)
  488. if image_deal_mode == 1:
  489. # 翻转
  490. im_shadow = im_shadow.transpose(Image.FLIP_LEFT_RIGHT)
  491. cut_image = cut_image.transpose(Image.FLIP_LEFT_RIGHT)
  492. # 创建底层背景
  493. image_bg = Image.new("RGB", (1600, 1600), (255, 255, 255))
  494. image_bg_x, image_bg_y = image_bg.size
  495. image_x, image_y = im_shadow.size
  496. _x = int((image_bg_x - image_x) / 2)
  497. _y = int((image_bg_y - image_y) / 2)
  498. image_bg.paste(im_shadow, (_x, _y))
  499. image_bg.paste(cut_image, (_x, _y), cut_image) # 再叠加原图避免色差
  500. if "小苏" in settings.Company:
  501. # 所有主图加logo
  502. is_logo = True
  503. if is_logo:
  504. # logo_path = ""
  505. # if settings.PROJECT == "红蜻蜓":
  506. # logo_path = r"resources\LOGO\HQT\logo.png"
  507. # elif settings.PROJECT == "惠利玛":
  508. # if "小苏" in settings.Company:
  509. # logo_path = r"resources\LOGO\xiaosushuoxie\logo.png"
  510. # elif "惠利玛" in settings.Company:
  511. # logo_path = r"resources\LOGO\HLM\logo.png"
  512. # else:
  513. # pass
  514. if not logo_path:
  515. logo_im = Image.new("RGBA", (1600, 1600), (0, 0, 0, 0))
  516. else:
  517. if os.path.exists(logo_path):
  518. logo_im = Image.open(logo_path)
  519. else:
  520. logo_im = Image.new("RGBA", (1600, 1600), (0, 0, 0, 0))
  521. image_bg.paste(logo_im, (0, 0), logo_im)
  522. # image_bg = image_bg.resize((out_pic_size, out_pic_size), Image.BICUBIC)
  523. if settings.OUT_PIC_FACTOR > 1.0:
  524. print("图片锐化处理")
  525. image_bg = sharpen_image(image_bg, factor=settings.OUT_PIC_FACTOR)
  526. if out_pic_size < 1600:
  527. image_bg = image_bg.resize(
  528. (out_pic_size, out_pic_size), resample=settings.RESIZE_IMAGE_MODE
  529. )
  530. if settings.OUT_PIC_MODE == ".jpg":
  531. if settings.OUT_PIC_QUALITY == "普通":
  532. self.saver.save_image(
  533. image=image_bg,
  534. file_path=out_path,
  535. save_mode="jpg",
  536. quality=None,
  537. dpi=None,
  538. _format="JPEG",
  539. )
  540. # save_image_by_thread(image_bg, out_path, save_mode="jpg", quality=None, dpi=None, _format="JPEG")
  541. # image_bg.save(out_path, format="JPEG")
  542. else:
  543. self.saver.save_image(
  544. image=image_bg,
  545. file_path=out_path,
  546. save_mode="jpg",
  547. quality=100,
  548. dpi=(300, 300),
  549. _format="JPEG",
  550. )
  551. # save_image_by_thread(image_bg, out_path, save_mode="jpg", quality=100, dpi=(300, 300), _format="JPEG")
  552. # image_bg.save(out_path, quality=100, dpi=(300, 300), format="JPEG")
  553. else:
  554. self.saver.save_image(image=image_bg, file_path=out_path, save_mode="png")
  555. # image_bg.save(out_path)
  556. if output_queue is not None:
  557. output_queue.put(True)
  558. return True