批量压缩png和jpg图片python3脚本工具

  • A+
所属分类:python基础入门

一、GGTinypng

批量压缩png和jpg图片python脚本工具,减少图片50%以上的大小,肉眼看不出差别。减量不减质。 图片数量少的话可以在tinypng.com上试一下。看下效果。

已经支持子文件夹里面的图片,会按原始的相对路径存放到输出文件夹内

7.30 新加功能:一条命令压缩整个项目内的图片。

显著降低app的大小

二、使用方法

可以使用alias来简化命令 python3 tinypng.py -i -o

-o 参数可以为空,因为要遍历picDocPath子文件夹 所以默认outputDocPath改为picDocPath父目录 内的outputTinypng文件夹,与picDocPath同级。

7.30 新参数:python3 tinypng.py -r <项目路径或者项目内某个图片文件夹的路径>

-r 参数会压缩文件夹内的图片并替换原图片

去 https://tinypng.com/developers 免费申请自己的key 每key每月免费压缩500个图

默认并发数为10 可以自己调整

三、源码

  1. #!/usr/bin/env?python3
  2. #?coding=utf-8
  3. #?from?os.path?import?dirname
  4. import?os,sys,?getopt
  5. from?urllib.request?import?Request,?urlopen
  6. from?base64?import?b64encode
  7. from?multiprocessing?import?Pool
  8. poolLimite?=?10
  9. key?=?"PX-pm9lAY3siS8cHIWz44zWFZHj6TtYX"
  10. #?input?=?"large-input.png"
  11. #?output?=?"tiny-output.png"
  12. opts,?args?=?getopt.getopt(sys.argv[1:],?"hi:o:r:")
  13. input_doc_path=""
  14. output_doc_path?=?''
  15. filePaths=[]
  16. for?op,?value?in?opts:
  17. ????if?op?==?"-i":
  18. ????????input_doc_path?=?value
  19. ????elif?op?==?"-o":
  20. ????????output_doc_path?=?value
  21. ????elif?op?==?"-r":
  22. ????????input_doc_path?=?value
  23. ????????output_doc_path?=?value
  24. ????elif?op?==?"-h":
  25. ????????print('''
  26. ????????使用方法?python3?tinypng.py?-i?picDocPath?-o?outputDocPath
  27. ????????-o?参数可以为空,默认存在picDocPath/tinypng?内
  28. ????????去?https://tinypng.com/developers?申请自己的key?每key每月免费压缩500个图
  29. ????????默认并发数为10?可以自己调整''')
  30. def?absFilePath(fileName):
  31. ????return?os.path.join(input_doc_path,fileName)
  32. def?getTinyPng(filePath):
  33. ????print('开始'+filePath)
  34. ????request?=?Request("https://api.tinify.com/shrink",?open(filePath,?"rb").read())
  35. ????cafile?=?None
  36. ????#?Uncomment?below?if?you?have?trouble?validating?our?SSL?certificate.
  37. ????#?Download?cacert.pem?from:?http://curl.haxx.se/ca/cacert.pem
  38. ????#?cafile?=?dirname(__file__)?+?"/cacert.pem"
  39. ????auth?=?b64encode(bytes("api:"?+?key,?"ascii")).decode("ascii")
  40. ????request.add_header("Authorization",?"Basic?%s"?%?auth)
  41. ????response?=?urlopen(request,?cafile?=?cafile)
  42. ????if?response.status?==?201:
  43. ??????#?Compression?was?successful,?retrieve?output?from?Location?header.
  44. ??????result?=?urlopen(response.getheader("Location"),?cafile?=?cafile).read()
  45. ??????output?=?os.path.join(output_doc_path,?os.path.relpath(filePath,input_doc_path))
  46. ??????open(output,?"wb").write(result)
  47. ??????print('完成'+output)
  48. ????else:
  49. ??????print('失败'+filePath)
  50. ??????#?Something?went?wrong!?You?can?parse?the?JSON?body?for?details.
  51. ??????print("Compression?failed")
  52. def?main():
  53. ????global?output_doc_path
  54. ????if?output_doc_path?==?'':
  55. ????????output_doc_path?=?os.path.join(os.path.split(input_doc_path)[0],?'outputTinypng')
  56. ????if?not?os.path.exists(output_doc_path):
  57. ????????os.mkdir(output_doc_path)
  58. ????for?parent,dirnames,filenames?in?os.walk(input_doc_path):????#三个参数:分别返回1.父目录?2.所有文件夹名字(不含路径)?3.所有文件名字
  59. ??????for?dirname?in??dirnames:???????????????????????#输出文件夹信息
  60. ????????#?print("parent?is:"?+?parent)
  61. ????????#?print("dirname?is"?+?dirname)
  62. ????????outDir?=?os.path.join(output_doc_path,os.path.relpath(os.path.join(parent,dirname),input_doc_path))
  63. ????????if?not?os.path.exists(outDir):
  64. ????????????os.mkdir(outDir)
  65. ??????for?filename?in?filenames:????????????????????????#输出文件信息
  66. ????????#?print("parent?is:"?+?parent)
  67. ????????#?print("filename?is:"?+?filename)
  68. ????????filePaths.append(os.path.join(parent,filename))
  69. ????pngFilePaths?=?filter(lambda?x:os.path.splitext(x)[1]=='.png'?or?os.path.splitext(x)[1]=='.jpg',filePaths)
  70. ????print('Parent?process?%s.'?%?os.getpid())
  71. ????p?=?Pool(poolLimite)
  72. ????for?fileName?in?pngFilePaths:
  73. ????????p.apply_async(getTinyPng,?args=(fileName,))
  74. ????print('Waiting?for?all?subprocesses?done...')
  75. ????p.close()
  76. ????p.join()
  77. ????print('All?subprocesses?done.')
  78. if?__name__=='__main__':
  79. ????if?os.path.isdir(input_doc_path):
  80. ????????main()
  • 我的微信
  • 这是我的微信扫一扫
  • weinxin
  • 我的微信公众号
  • 我的微信公众号扫一扫
  • weinxin

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: