manifest.py 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. # -*- coding: utf-8 -*-
  2. # @Author: bymoye
  3. # @Date: 2021-06-02 12:13:43
  4. # @Last Modified by: bymoye
  5. # @Last Modified time: 2022-03-24 22:33:17
  6. import os,json
  7. from PIL import Image
  8. from concurrent import futures
  9. from hashlib import md5
  10. FORMAT = ('webp','jpeg')
  11. SIZE = ('source','th')
  12. THUMBNAIL = (900,600)
  13. MD = (50,30)
  14. # 过滤尺寸 要开设置
  15. PCSIZE = (1920,1080)
  16. MOBILESIZE = (900,1200)
  17. FILTERTYPE = ('pc','mobile')
  18. class ProcessImage():
  19. def __init__(self,flush: bool,filter: bool) -> None:
  20. if not os.path.exists('./jpeg'):
  21. os.mkdir('./jpeg')
  22. if not os.path.exists('./webp'):
  23. os.mkdir('./webp')
  24. self.pc = dict()
  25. self.mobile = dict()
  26. self.md5set = set()
  27. self.errorfiles = list()
  28. self.repeatfiles = list()
  29. self.failedfiles = list()
  30. self.status = {
  31. 'Trueid':0,
  32. 'Falseid':0,
  33. 'Repeatid':0,
  34. 'Failedid':0,
  35. }
  36. self.flush = flush
  37. self.filter = filter
  38. def process_image(self,file):
  39. try:
  40. source = open('gallary/' + file,'rb')
  41. _hash = md5(source.read()).hexdigest()
  42. if _hash in self.md5set:
  43. source.close()
  44. return 1
  45. image = Image.open(source).convert('RGB')
  46. except Exception as e:
  47. print(f'error : {e}')
  48. return 0
  49. width , height = image.size
  50. platform = "mobile" if width < height else "pc"
  51. if self.filter:
  52. filterwidth , filterheight = PCSIZE if platform == "pc" else MOBILESIZE
  53. if width < filterwidth or height < filterheight:
  54. source.close()
  55. image.close()
  56. return 2
  57. for format in FORMAT:
  58. _image = image.copy()
  59. for size in SIZE:
  60. if size == 'th':
  61. _image.thumbnail(THUMBNAIL)
  62. if size == 'md':
  63. _image.thumbnail(MD)
  64. if format == 'jpeg':
  65. _image.save(f"{format}/{_hash}.{size}.{format}",format.upper(), quality=90, subsampling=0, progressive = True)
  66. else:
  67. _image.save(f"{format}/{_hash}.{size}.{format}",format.upper(),quality=90, subsampling=0)
  68. source.close()
  69. image.close()
  70. _image.close()
  71. self.md5set.add(_hash)
  72. return {platform:{_hash:{'source':file}}}
  73. def try_process(self):
  74. if not os.path.exists('./gallary'):
  75. os.mkdir('./gallary')
  76. print('gallary文件夹不存在,已自动创建,请在该文件夹下放图片,再运行此程序')
  77. return False
  78. filenames = [file for file in os.listdir('gallary') if os.path.isfile(os.path.join('gallary', file))]
  79. if not self.flush:
  80. if os.path.exists('manifest.json'):
  81. with open('manifest.json','r') as f:
  82. if f.read():
  83. manifest = json.load(f)
  84. _manifest = [i['source'] for i in list(manifest.values())]
  85. self.md5set = self.md5set | {i for i in manifest.keys()}
  86. filenames = list(set(filenames) - set(_manifest))
  87. self.pc = {**manifest}
  88. if os.path.exists('manifest_mobile.json'):
  89. with open('manifest_mobile.json','r') as f:
  90. if f.read():
  91. manifest = json.load(f)
  92. _manifest = [i['source'] for i in manifest.values()]
  93. self.md5set = self.md5set | {i for i in manifest.keys()}
  94. filenames = list(set(filenames) - set(_manifest))
  95. self.mobile = {**manifest}
  96. fileslen = len(filenames)
  97. progress = 0
  98. with futures.ProcessPoolExecutor(max_workers=8) as executor:
  99. for result in zip(filenames,executor.map(self.process_image, filenames)):
  100. filename , imgprocess = result
  101. if imgprocess == 0:
  102. self.status['Falseid'] += 1
  103. self.errorfiles.append(filename)
  104. print(f"\n出现错误文件:{filename}")
  105. elif imgprocess == 1:
  106. self.status['Repeatid'] += 1
  107. self.repeatfiles.append(filename)
  108. print(f"\n{filename} 已存在")
  109. elif imgprocess == 2:
  110. self.status['Failedid'] += 1
  111. self.failedfiles.append(filename)
  112. print(f"\n{filename} 尺寸不达标")
  113. else:
  114. self.status['Trueid'] += 1
  115. if imgprocess.get('pc'):
  116. self.pc.update(imgprocess['pc'])
  117. elif imgprocess.get('mobile'):
  118. self.mobile.update(imgprocess['mobile'])
  119. progress += 1
  120. print(f"\r{filename} 已进行处理,进度 {progress}/{fileslen}",end="",flush=True)
  121. with open('manifest.json','w+') as json_file:
  122. json.dump(self.pc,json_file)
  123. with open('manifest_mobile.json','w+') as json_file:
  124. json.dump(self.mobile,json_file)
  125. print(f"""
  126. 任务已完成
  127. 总计数量:{fileslen}
  128. 成功数量:{self.status['Trueid']}
  129. 失败数量:{self.status['Falseid']}
  130. 失败文件:{self.errorfiles}
  131. 重复数量:{self.status['Repeatid']}
  132. 重复文件:{self.repeatfiles}
  133. 不合格数量:{self.status['Failedid']}
  134. 不合格文件:{self.failedfiles}
  135. 当前总计 pc 图片数量:{len(self.pc)}
  136. 当前总计 mobile 图片数量:{len(self.mobile)}
  137. """)
  138. if __name__ == '__main__':
  139. # 如果 flush 为True 将会清空原有的manifest.json文件
  140. # 如果 flush 为False 将会追加新的manifest.json文件
  141. # 如果filter 为True 将会过滤掉不合格的图片
  142. temp = ProcessImage(flush=False,filter=False)
  143. temp.try_process()