天天看点

用小于99行的python代码实现批量图片格式转换(带GUI)

最近需要用到批量图片转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
           

用我珍藏多年的小姐姐测试一下,部分测试截图:

用小于99行的python代码实现批量图片格式转换(带GUI)
用小于99行的python代码实现批量图片格式转换(带GUI)

转换后的:

用小于99行的python代码实现批量图片格式转换(带GUI)

代码和打包好的exe在这:

https://download.csdn.net/download/pirate7777777/16312636

The end...

那啥,其实我又改了下代码,放弃easygui了,传送门。