鱼C论坛

 找回密码
 立即注册
查看: 3245|回复: 65

[其他] 火爆全球的主流图片压缩方案自动化脚本(有彩蛋)

[复制链接]
发表于 2023-3-4 03:12:42 | 显示全部楼层 |阅读模式
购买主题 已有 12 人购买  本主题需向作者支付 10 鱼币 才能浏览
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-3-19 21:16:06 | 显示全部楼层
  1. import os, sys
  2. import tinify

  3. tinify.key = 'key'
  4. ext = ['.jpg', '.png', '.webp']

  5. def compressPictures(showProgress):
  6.     def compress(*args):
  7.         progress = showProgress(*args)
  8.         pic = args[0]
  9.         wh = args[1]
  10.         try:
  11.             source = tinify.from_file(pic)
  12.             if wh:
  13.                 picWidth = wh[0]
  14.                 picHeight = wh[1]
  15.                 if picWidth==0 or picHeight==0:
  16.                     method = 'scale'
  17.                     if picWidth==0:
  18.                         resized = source.resize(method=method, height=picHeight)
  19.                     else:
  20.                         resized = source.resize(method=method, width=picWidth)
  21.                 else:
  22.                     resized = source.resize(method='fit', width=picWidth, height=picHeight)
  23.                 resized.to_file(pic)   
  24.             else:
  25.                 source.to_file(pic)
  26.                
  27.         except tinify.AccountError as e:
  28.             print('错误 -> 请检查tinify密钥 或 帐户限制。\n')
  29.         except tinify.ClientError as e:
  30.             print('错误 -> 请检查源图片 或 请求选项。\n')
  31.         except tinify.ServerError as e:         
  32.             print('错误 -> Tinify API临时问题。\n')
  33.         except tinify.ConnectionError as e:
  34.             print('错误 -> 网络连接错误。\n')
  35.         except Exception as e:
  36.             print(f'错误 -> {str(e)}。\n')
  37.         
  38.         return progress
  39.    
  40.     return compress

  41. @compressPictures
  42. def showProgress(pic, wh, idx, total):
  43.     pic = os.path.basename(pic)
  44.     print(f'({idx}/{total})图片<{pic}>正在压缩处理中,请稍后...')
  45.    
  46. def startCompress(picList, wh):
  47.     total = len(picList)
  48.     for i, pic in enumerate(picList):
  49.         showProgress(pic, wh, i+1, total)
  50.     print('全部处理完成~')   
  51.    
  52. if __name__ == '__main__':
  53.     picList = []
  54.     pathList = sys.argv
  55.     if len(pathList)>1:
  56.         # 实现拖拽到源文件上进行压缩
  57.         for path in pathList:
  58.             if not os.path.isdir(path) and os.path.splitext(path)[1].lower() in ext:
  59.                 picList.append(path)
  60.     else:
  61.         src = input('请输入需要压缩的图片名称(回车优化当前文件夹):')        
  62.         if src.strip()=='':
  63.             print('开始优化当前文件夹下所有的jpg/png/webp图片')        
  64.             pyPath = os.getcwd()
  65.             for file in os.listdir(pyPath):
  66.                 path = os.path.join(pyPath, file)
  67.                 if not os.path.isdir(path) and os.path.splitext(path)[1].lower() in ext:
  68.                     picList.append(path)      
  69.         else:
  70.             picList.append(src)
  71.     if not picList:            
  72.         input('当前未选择jpg/png/webp类型的图片。按回车退出程序...')
  73.         exit()

  74.     wh = input('请输入尺寸(宽度 高度)')
  75.     wh = [int(n) for n in wh.strip().split()]

  76.     startCompress(picList, wh)

  77.     input('按回车退出程序...')
复制代码

点评

我很赞同!: 5.0
我很赞同!: 5
恭喜,成功实现需求,获得第一名(1000C币)奖励^o^  发表于 2023-3-25 03:20
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 2 反对 0

使用道具 举报

发表于 2023-3-20 02:11:25 | 显示全部楼层
本帖最后由 hrpzcf 于 2023-3-20 12:18 编辑
  1. # coding: utf-8

  2. import os
  3. import sys
  4. from typing import *

  5. import tinify

  6. SUPPORTED = ".jpg", ".jpeg", ".png", ".webp"
  7. OPTED_PREFIX = "optimized"
  8. tinify.key = "xxxxxxxxxxxx"


  9. def clean_filenames(files: List[str]) -> List[str]:
  10.     valid_files = []
  11.     for f in files:
  12.         if f and os.path.isfile(f):
  13.             if os.path.splitext(f)[1].lower() in SUPPORTED:
  14.                 valid_files.append(f)
  15.     return valid_files


  16. def receive_filenames() -> List[str]:
  17.     if len(sys.argv) > 1:
  18.         image_files = clean_filenames(sys.argv[1:])
  19.         if not image_files:
  20.             input("没有拖入任何有效的图片文件,按回车关闭后请重试...")
  21.             sys.exit(1)
  22.         return image_files
  23.     while True:
  24.         names = input("请输入要压缩的图片名称(回车压缩当前文件夹):")
  25.         if names:
  26.             image_files = clean_filenames(names.split())
  27.         else:
  28.             try:
  29.                 image_files = clean_filenames(os.listdir(os.curdir))
  30.             except PermissionError:
  31.                 print("无法列举当前文件夹下的文件,请用其他方式指定...")
  32.                 continue
  33.         if not image_files:
  34.             print("没有找到符合要求的图片,请重新指定...")
  35.             continue
  36.         return image_files


  37. def compression_config() -> Tuple[int, int]:
  38.     width, height = 0, 0
  39.     while True:
  40.         input_str = input("请输入尺寸(宽度 高度):")
  41.         if not input_str:
  42.             break
  43.         config = input_str.split(" ", 1)
  44.         if len(config) != 2:
  45.             print("请以空格分隔宽度和高度数值...")
  46.             continue
  47.         try:
  48.             width = int(config[0])
  49.             height = int(config[1])
  50.         except ValueError:
  51.             print("请输入正确的宽度和高度数值...")
  52.             continue
  53.         if width >= 0 and height >= 0 and not (width == 0 and height == 0):
  54.             break
  55.         else:
  56.             print("宽高数值必须大于等于零且不能同时等于零...")
  57.     return width, height


  58. def show_progress(func: Callable[[str], None]):
  59.     def inner_func(files: List[str], width: int, height: int):
  60.         length = len(files)
  61.         for i, p in enumerate(files, 1):
  62.             base = os.path.basename(p)
  63.             print("(%d/%d)图片<%s>正在压缩处理中,请稍后..." % (i, length, base))
  64.             func(os.path.abspath(p), width, height)
  65.         print("全部处理完成 ~")

  66.     return inner_func


  67. @show_progress
  68. def start_compression(filepath: str, width: int, height: int):
  69.     count = 0
  70.     parent, base = os.path.split(filepath)
  71.     while True:
  72.         new_name = "%s%d_%s" % (OPTED_PREFIX, count, base)
  73.         new_fullpath = os.path.join(parent, new_name)
  74.         if not os.path.exists(new_fullpath):
  75.             break
  76.         count += 1
  77.     try:
  78.         source = tinify.from_file(filepath)
  79.         if width > 0 and height == 0:
  80.             source = source.resize(method="scale", width=width)
  81.         elif width == 0 and height > 0:
  82.             source = source.resize(method="scale", height=height)
  83.         elif width > 0 and height > 0:
  84.             source = source.resize(method="fit", width=width, height=height)
  85.         source.to_file(new_fullpath)
  86.     except tinify.AccountError:
  87.         print("帐户异常~")
  88.     except tinify.ClientError:
  89.         print("客户端异常~")
  90.     except tinify.ServerError:
  91.         print("服务器异常~")
  92.     except tinify.ConnectionError:
  93.         print("网络连接异常~")
  94.     except Exception as e:
  95.         print("未知异常:%s" % e)


  96. def main():
  97.     filenames = receive_filenames()
  98.     config = compression_config()
  99.     start_compression(filenames, *config)


  100. if __name__ == "__main__":
  101.     main()
  102.     input("按回车退出...")
复制代码

点评

我很赞同!: 5.0
我很赞同!: 5
恭喜,成功实现需求,获得第二名(600C币)奖励^o^  发表于 2023-3-25 03:21
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-4 08:20:25 | 显示全部楼层
好东西,学习学习~
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-4 08:55:25 | 显示全部楼层
小甲鱼解决了我的pip不是内部或外部指令,好耶
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-4 09:04:08 | 显示全部楼层
sfqxx 发表于 2023-3-4 08:55
小甲鱼解决了我的pip不是内部或外部指令,好耶

那不就是
  1. py -m
复制代码

吗?
(python可以简写成py)
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-5 20:18:22 | 显示全部楼层

嗯嗯呐
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-12 15:56:29 | 显示全部楼层
竟然有C币!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-13 19:59:39 | 显示全部楼层
本帖最后由 liuhongrun2022 于 2023-3-13 20:18 编辑

甲鱼老师,花一点时间写了一个,您看一下
有什么建议可以修改

  1. import tinify
  2. import os
  3. from tkinter.filedialog import *

  4. tinify.key = "API Key"

  5. print("图片压缩程序".center(20, "-"))


  6. def compressed_image():
  7.     print("-" * 20)
  8.     select_url_or_file = int(input("从本地文件还是URL上传?\n输入1从本地文件上传\n输入2从URL上传\n请选择模式:"))
  9.     if select_url_or_file == 1:
  10.         file = askopenfilename(
  11.             title="选择图像文件", filetypes=[("图像文件", "*.jpg;*.png;*.jpeg;*.webp")]
  12.         )
  13.         size = input("请输入图片宽高,使用空格隔开,如果没有请留空:")
  14.         if len(size.split()) == 0:
  15.             print(f"正在处理图片 {os.path.split(file)[1]} ...")
  16.             source = tinify.from_file(file)
  17.             source.to_file(f"{os.path.split(file)[0]}/opt_{os.path.split(file)[1]}")
  18.             print("压缩成功!")
  19.             print("-" * 20)
  20.         elif len(size.split()) == 2:
  21.             print(f"正在处理图片 {os.path.split(file)[1]} ...")
  22.             source = tinify.from_file(file)
  23.             resized = source.resize(
  24.                 method="fit", width=int(size.split()[0]), height=int(size.split()[1])
  25.             )
  26.             resized.to_file(f"{os.path.split(file)[0]}/opt_{os.path.split(file)[1]}")
  27.             print("压缩成功!")
  28.             print("-" * 20)
  29.         else:
  30.             print("请输入正确的宽高数值!")
  31.     elif select_url_or_file == 2:
  32.         url = input("请输入要压缩图片的URL:")
  33.         size = input("请输入图片宽高,使用空格隔开,如果没有请留空:")
  34.         if len(size.split()) == 0:
  35.             print(f"正在处理图片 {os.path.split(url)[1]} ...")
  36.             source = tinify.from_url(url)
  37.             source.to_file(f"{os.getcwd()}/{os.path.split(url)[1]}")
  38.             print("压缩成功!")
  39.             print("-" * 20)
  40.         elif len(size.split()) == 2:
  41.             print(f"正在处理图片 {os.path.split(file)[1]} ...")
  42.             source = tinify.from_url(url)
  43.             resized = source.resize(
  44.                 method="fit", width=int(size.split()[0]), height=int(size.split()[1])
  45.             )
  46.             resized.to_file(f"{os.getcwd()}/{os.path.split(url)[1]}")
  47.             print("压缩成功!")
  48.             print("-" * 20)


  49. def compressed_images():
  50.     folder = askdirectory(title="选择目录")
  51.     size = input("请输入图片宽高,使用空格隔开,如果没有请留空:")
  52.     dirs = os.listdir(folder)
  53.     for i in dirs:
  54.         if (
  55.             os.path.splitext(i)[1] == ".jpg"
  56.             or os.path.splitext(i)[1] == ".png"
  57.             or os.path.splitext(i)[1] == ".jpeg"
  58.             or os.path.splitext(i)[1] == ".webp"
  59.         ):
  60.             if len(size.split()) == 0:
  61.                 print(f"正在处理图片 {i} ...")
  62.                 source = tinify.from_file(f"{folder}/{i}")
  63.                 source.to_file(f"{folder}/opt_{i}")
  64.                 print("压缩成功!")
  65.                 print("-" * 20)
  66.             elif len(size.split()) == 2:
  67.                 print(f"正在处理图片 {i} ...")
  68.                 source = tinify.from_file(f"{folder}/{i}")
  69.                 resized = source.resize(
  70.                     method="fit",
  71.                     width=int(size.split()[0]),
  72.                     height=int(size.split()[1]),
  73.                 )
  74.                 resized.to_file(f"{folder}/opt_{i}")
  75.                 print("压缩成功!")
  76.                 print("-" * 20)


  77. while True:
  78.     select = int(input("输入1为单个图片压缩\n输入2为批量压缩\n输入-1退出\n请选择模式:"))
  79.     if select == -1:
  80.         break
  81.     elif select == 1:
  82.         compressed_image()
  83.     elif select == 2:
  84.         compressed_images()
复制代码

点评

很遗憾,代码并没有按【需求描述】进行实现。  发表于 2023-3-25 03:11
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-15 08:35:59 | 显示全部楼层
代码发不出去呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-15 08:36:44 | 显示全部楼层
  1. import os
  2. import tinify
  3. import sys

  4. # tinify.key ='dMKLVMY#####4lkBDK6BVKYY'
  5. def yasuo(file):
  6. #     source = tinify.from_file(file)
  7. #     source.to_file(file)
  8.     pass
  9. def get_name():
  10.     name = input('请输入您要压缩的图片名称(回车优化当前文件夹):') #输入名称
  11.     if len(name)>0:  #确认已经输入成功
  12.         dir_exist(name)   #判断输入的信息是否存在
  13.     else:   #如果没有输入信息,就批判当前文件夹
  14.         print('当前文件夹为{}\\'.format(sys.path[0]))
  15.         file_dir = os.listdir(sys.path[0])
  16.         j = 0
  17.         for i in file_dir:
  18.             if i.find('jpg') > 0 or i.find('png')>0 or i.find('webp')>0:
  19.                 print("图片{}正在压缩处理中,请稍后。。。".format(i))
  20.                 j = j + 1
  21.             else:
  22.                 pass
  23.         if j == 0:
  24.             print("在该文件夹下面啥呀没找到啊!!")

  25. def dir_exist(path):
  26.     if os.path.exists(path):   #如果存在,就准备执行脚本
  27.         res=doit(path)
  28.     else:       #如果不存在,就只能再让人工核对
  29.         print('您输入的文件名称地址[{}]不对,请核实您填入的地址!'.format(path))
  30.         print('==================')
  31.         get_name()

  32. #判断传入的文件或者文件夹中是否有 jpg/png/webp 图片
  33. def doit(file):
  34.     print('哇塞!你输入的地址是对的哎!现在需要判断你输入的是文件名还是文件夹名!')
  35.     print('你输入的是{}'.format(file))
  36.     if file.find('.')>0: #如果输入的信息里面有'.'就代表是文件
  37.         print('很棒!你直接输入的是文件!我看看是不是jpg/png/webp 图片')
  38.         if file.find('jpg')>0 or file.find('png')>0 or file.find('webp')>0:
  39.             print('************************')
  40.             print("图片{}正在压缩处理中,请稍后。。。".format(file))
  41.             print('************************')
  42.         else:
  43.             print("你输入的地址{}虽然找到了,但是它不是jpg/png/webp 图片,我也没法操作!".format(file))
  44.             print('您输入的文件名称地址[{}]不对,请核实您填入的地址!'.format(file))
  45.             print('==================')
  46.             get_name()
  47.     else:                   # 那就是文件夹了
  48.         print('你输入的是文件夹!我看看它里面是不是jpg/png/webp 图片')
  49.         file_dir = os.listdir(file)
  50.         j = 0
  51.         for i in file_dir:
  52.             if i.find('jpg') > 0 or i.find('png')>0 or i.find('webp')>0:
  53.                 print("图片{}正在压缩处理中,请稍后。。。".format(i))
  54.                 yasuo(i)
  55.                 j = j + 1
  56.             else:
  57.                 pass
  58.         if j == 0:
  59.             print("在该文件夹下面啥呀没找到啊!!")
  60.             print('您输入的文件名称地址[{}]不对,请核实您填入的地址!'.format(file))
  61.             print('==================')
  62.             get_name()


  63.     pass


  64. if __name__ == '__main__':
  65.     file_name=get_name()
复制代码



点评

很遗憾,代码并没有按【需求描述】进行实现。  发表于 2023-3-25 03:11
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-3-24 12:09:39 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-3-24 18:05:53 | 显示全部楼层
代码揭晓呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-5 11:54:55 | 显示全部楼层
1111111
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-6 22:02:33 | 显示全部楼层
打卡!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-7 11:15:50 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-13 20:34:04 | 显示全部楼层
6
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-13 23:17:46 | 显示全部楼层
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2023-4-28 10:30:27 | 显示全部楼层
朕想知道
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2023-4-29 18:51:15 | 显示全部楼层
朕想知道
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-4-24 12:43

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表