最近需要用到批量图片转webp的功能,忍不住手痒,撸了会儿代码。主要实现以下功能:
1.批量图片的格式转换:
几种常见图片格式相互转换:webp,jpg,png,bmp
2.最好有GUI,方便交互。
3.顺手打包成了exe以后可以直接双击使用。
用了pillow和easygui做了简单的实现:
部分功能实现:
1.遍历文件夹,返回所有符合的图片路径到列表内
# 遍历文件夹,返回所有符合的图片路径到列表内
def getImages(filePath=os.getcwd()):
file_list = []
for home, _dirs, files in os.walk(filePath):
for fi in files:
_name, end = os.path.splitext(fi)
if end.lower() in IMG_TARGETS:
file_list.append(os.path.join(home, fi))
return file_list
2.转换图片
# 转换图片
def convertImage(input_name, out_path, img_exp='.webp'):
if not (os.path.exists(out_path)):
os.makedirs(out_path)
basename = os.path.basename(input_name) # 文件名
filename, _end = os.path.splitext(basename) # 分离文件名与扩展名
output_name = os.path.join(out_path, filename + img_exp) # 拼接输出的文件名,带路径
im = Image.open(input_name)
im.load() # required for png.split()
# TODO
# https://pillow.readthedocs.io/en/5.1.x/handbook/image-file-formats.html#fully-supported-formats
# im.convert('RGB')
if im.mode == "RGBA": # jpg
background = Image.new("RGB", im.size, (255, 255, 255))
background.paste(im, mask=im.split()[3]) # 3 is the alpha channel
im = background
im.save(output_name) # pillow可以自动通过后缀推断文件名
print('==>', output_name, '\n>>done!\n')
到了这里,不用GUI其实转换图片的功能已经实现了,可以直接测试:
for img in getImages():
convertImage(img, os.getcwd()+'\\out')
为了以后偷懒,就随便加个GUI好了,以下是全部实现的代码:
#!/usr/bin/env python3
# pip install pillow easygui
import os
import sys
import easygui as eg
from PIL import Image
# 需要转换的文件格式 其他支持的格式也可以加进去如'.tif',不过没测试,不知道会出什么问题
IMG_TARGETS = ['.webp', '.jpg', '.png', '.bmp']
TITLE = "图片格式转换" # 窗口标题
# 遍历文件夹,返回所有符合的图片路径到列表内
def getImages(filePath=os.getcwd()):
file_list = []
for home, _dirs, files in os.walk(filePath):
for fi in files:
_name, end = os.path.splitext(fi)
if end.lower() in IMG_TARGETS:
file_list.append(os.path.join(home, fi))
return file_list
# 转换图片
def convertImage(input_name, out_path, img_exp='.webp'):
if not (os.path.exists(out_path)):
os.makedirs(out_path)
basename = os.path.basename(input_name) # 文件名
filename, _end = os.path.splitext(basename) # 分离文件名与扩展名
output_name = os.path.join(out_path, filename + img_exp) # 拼接输出的文件名,带路径
im = Image.open(input_name)
im.load() # required for png.split()
# TODO
# https://pillow.readthedocs.io/en/5.1.x/handbook/image-file-formats.html#fully-supported-formats
# im.convert('RGB')
if im.mode == "RGBA": # jpg
background = Image.new("RGB", im.size, (255, 255, 255))
background.paste(im, mask=im.split()[3]) # 3 is the alpha channel
im = background
im.save(output_name) # pillow可以自动通过后缀推断文件名
print('==>', output_name, '\n>>done!\n')
def main():
# 页面1
msg = '''
Wellcome!\n\n\n
请按照引导开始图片转换!
1.选择需要转换的文件夹
2.选择输出的文件夹
3.选择输出的图像类型
4.确认
\n\n\n\n\n
--by pirate7777777
2021-04-01
'''
if (eg.msgbox(msg, title=TITLE) is None):
sys.exit(0)
# 页面1 选择需要转换的文件夹
workpath = eg.diropenbox(
msg="请选择需要转换的文件夹", title=TITLE, default=os.getcwd())
if (workpath is None): # 取消则workpath为空,退出,下同
sys.exit(0)
# 页面2 选择输出的文件夹
out_path = eg.diropenbox(
msg="请选择输出的文件夹", title=TITLE, default=os.getcwd() + "\\out")
if (out_path is None):
sys.exit(0)
# 页面3 选择输出的文件类型
img_exp = eg.choicebox(
msg="请选择输出的图像类型", title=TITLE, choices=IMG_TARGETS)
if (img_exp is None):
sys.exit(0)
# IMG_TARGETS.remove(img_exp) # TODO 排除不用转换的图片后缀
imgList = getImages(workpath) # 转换的图片列表
# 页面4 确认信息
txt = '输出文件夹:' + out_path+'\n输出图像格式:' + img_exp + ('\n以下文件将被转换:')
txt2 = ''
for t in imgList:
txt2 = txt2 + t + '\n'
if(eg.textbox(msg=txt, title=TITLE, text=txt2)): # 按确定开始转换
for imgPath in imgList: # 逐个转换
convertImage(imgPath, out_path, img_exp)
eg.msgbox(msg='完成!', title=TITLE)
else:
sys.exit(0)
if __name__ == '__main__':
main()
# #test
# for img in getImages():
# convertImage(img, os.getcwd()+'\\out')
当然这其中必定有坑:
我用的是anaconda,libwebp还是pillow貌似有点问题。这里只记录我自己实测可用的解决方式:
conda uninstall pillow
然后:
pip install pillow
千万不要这么干!!!,不然就等着重装Anaconda吧,直接在python环境下装pillow好了。
顺便装一下我们要用到的easygui,和pillow:
pip install easygui
pip install pillow
pip install pyinstaller //打包工具
运行可用,直接打包(my.ico是我随便找的图标):
pyinstaller -Fw --icon=my.ico test.py
用我珍藏多年的小姐姐测试一下,部分测试截图:
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiIwczX0xiRGZkRGZ0Xy9GbvNGL2EzXlpXazxSPjpnTzMmeONzYUpFMG12YwJ0MMBjVtJWd0ckW65UbM5WOHJWa5kHT20ESjBjUIF2X0hXZ0xCMx81dvRWYoNHLrdEZwZ1Rh5WNXp1bwNjW1ZUba9VZwlHdssmch1mclRXY39CXldWYtlWPzNXZj9mcw1ycz9WL49zZuBnL0YjMwMzN0EjMxADNwEjMwIzLc52YucWbp5GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.png)
转换后的:
代码和打包好的exe在这:
https://download.csdn.net/download/pirate7777777/16312636
The end...
那啥,其实我又改了下代码,放弃easygui了,传送门。