python学习之使用PIL+tkinter实现自己的图片转换器

PIL提供了一个功能强大的库,可以转变原始图片格式,尺寸(可以不按比例放缩),质量等等,tkinter是一个轻量级的GUI软件,方便我们制作简单应用程序。
现在开始制作最简单的软件吧。
基本配置要求:自行安装python3.6(Aconada也可)+pil(pillow)+tkinter
涉及知识:文件读写,异常处理,GUI编程,global变量,回调函数
github:https://github.com/ivat4u/Black-Technology

如何转变图片格式

对Image模块的介绍,对于PNG、BMP和JPG彩色图像格式之间的互相转换都可以通过Image模块的open()和save()函数来完成。
具体说就是,在打开这些图像时,PIL会将它们解码为三通道的“RGB”图像。用户可以基于这个“RGB”图像,对其进行处理。
处理完毕,使用函数save(),可以将处理结果保存成PNG、BMP和JPG中任何格式。这样也就完成了几种格式之间的转换。

def call_convert(type='jpg')
	#选取目录文件
	path = tkinter.filedialog.askopenfilename()
	#获得父路径
	file_path=os.path.dirname(path)
	filename=os.path.basename(path)
	#文件名前缀
	front=filename.split('.')[0]
	#这段函数用来选取图片,如果是D:\\IMG.jpg  front会为IMG file_path=D:\\
    try:
            img = Image.open(path)
            output_path=file_path + '\\' + front + '.' + type
            output_file=img
            output_file.save(output_path)
	except OSError:
            lb.config(text="您没有选择任何文件")
            tkinter.messagebox.showerror('错误', '图片格式错误,无法识别')

现在根据你定义的type,就可以转变成不同格式了,PIL很强大,至少支持jpg,png,pdf,jpeg,bmp等常用格式转换哦。

定义button和监听器

选择最简单的块状布局,然后再button,command填入回调函数,大功告成。

root = Tk()
root.geometry()
root.title('图片格式转换')
lb = Label(root,text = '选取格式后会在原路径生成对应格式')
lb.pack()
#回调函数如果带参数,记得写成lamda表达式
btn = Button(root,text="转换图片",command=lambda:call_convert(type='jpg')
btn.pack()

这时候我们按钮button就可以响应转换一张选取的图片,并且输出同目录同名.type格式的图片了。

单选框指定格式

但是我们这个程序仍然不方便使用,我们希望做成这个样子的:
单选框
即利用单选框来选择图片格式。
首先定义全局变量的数组字典:

types=[('png',0),('jpg',1),('bmp',2),('pdf',3),('jpeg',4)]
type='png'

然后创建单选框和对应回调函数:

v=IntVar()
def callRB():
    for i in range(5):
        if (v.get()==i):
            global type
            type=types[i][0]
#for循环创建单选框
for lan,num in types:
    Radiobutton(fm1, text=lan, value=num, command=callRB, variable=v).pack(anchor=W,side='left')

经过反复测试,我们一定要把v的数字值写在types的第二项,v.get语句才能正常工作,如果不想用intvar可以改用StringVar(后面会用到)。
改写之前的转换函数:

#现在这个type是我们修改后的全局变量了
btn = Button(root,text="转换图片",command=lambda:call_convert(type)

经过测试,正常工作,OK

改变图片尺寸和pil滤镜

做到这里,你可能会疑问,我们辛辛苦苦写的软件,不如网站上下载的格式转换器,那有什么用呢?
现在我们就开始使用一些更强大的黑科技吧。
任意改变图片尺寸(可以不按比例放缩)

#这段代码后一个参数可以改变图片压缩率哦,不过我的代码通过save函数实现的
img=img.resize((180,180),Image.ANTIALIAS)
from PIL import Image, ImageFilter
#更多强大功能
im = Image.open(im_path)
# 高斯模糊
im.filter(ImageFilter.GaussianBlur).save(r'C:\Users\Administrator\Desktop\GaussianBlur.jpg')
# 普通模糊
im.filter(ImageFilter.BLUR).save(r'C:\Users\Administrator\Desktop\BLUR.jpg')
# 边缘增强
im.filter(ImageFilter.EDGE_ENHANCE).save(r'C:\Users\Administrator\Desktop\EDGE_ENHANCE.jpg')
# 找到边缘
im.filter(ImageFilter.FIND_EDGES).save(r'C:\Users\Administrator\Desktop\FIND_EDGES.jpg')
# 浮雕
im.filter(ImageFilter.EMBOSS).save(r'C:\Users\Administrator\Desktop\EMBOSS.jpg')
# 轮廓
im.filter(ImageFilter.CONTOUR).save(r'C:\Users\Administrator\Desktop\CONTOUR.jpg')
# 锐化
im.filter(ImageFilter.SHARPEN).save(r'C:\Users\Administrator\Desktop\SHARPEN.jpg')
# 平滑
im.filter(ImageFilter.SMOOTH).save(r'C:\Users\Administrator\Desktop\SMOOTH.jpg')
# 细节
im.filter(ImageFilter.DETAIL).save(r'C:\Users\Administrator\Desktop\DETAIL.jpg')

预览图

有些童鞋说你这软件太low了,居然不可以让我看到预览图,每次就点一个保存出现新图,自己都不知道效果怎么样?
OK,现在我们来做一个预览图和原图的功能,大致效果如下:
预览图
现在我们需要把加载图片,修改图片,确定分成三个回调函数了

#加载图片
def loadimg():
    global path
    global sizex
    global sizey
    path = tkinter.filedialog.askopenfilename()
    lb.config(text=path)
    if path != '':
        try:
            img = Image.open(path)
            sizex=img.size[0]
            sizey=img.size[1]
            x.set(sizex)
            y.set(sizey)
            img=img.resize((180,180),Image.ANTIALIAS)
            global img_origin
            img_origin = ImageTk.PhotoImage(img)
            global label_img
            label_img.configure(image=img_origin)
            label_img.pack()
        except OSError:
            tkinter.messagebox.showerror('错误', '图片格式错误,无法识别')
#修改图片
def convert(path,type='png',x=sizex,y=sizey,):
    x=int(x)
    y=int(y)
    file_path=os.path.dirname(path)
    filename=os.path.basename(path)
    front=filename.split('.')[0]
    def function(img):
        try:
            if (0 in cl_dict):
                img = img.convert('RGB').transpose(Image.FLIP_LEFT_RIGHT)
            if (1 in cl_dict):
                img = img.convert('RGB').transpose(Image.FLIP_TOP_BOTTOM)
            if (2 in cl_dict):
                img = img.convert('RGB').filter(ImageFilter.GaussianBlur)
            if (3 in cl_dict):
                img = img.convert('RGB').filter(ImageFilter.BLUR)
            if (4 in cl_dict):
                img = img.convert('RGB').filter((ImageFilter.EDGE_ENHANCE))
            if (5 in cl_dict):
                img = img.convert('RGB').filter(ImageFilter.FIND_EDGES)
            if (6 in cl_dict):
                img = img.convert('RGB').filter(ImageFilter.EMBOSS)
            if (7 in cl_dict):
                img = img.convert('RGB').filter(ImageFilter.CONTOUR)
            if (8 in cl_dict):
                img = img.convert('RGB').filter(ImageFilter.SHARPEN)
            if (9 in cl_dict):
                img = img.convert('RGB').filter(ImageFilter.SMOOTH)
            if (10 in cl_dict):
                img = img.convert('RGB').filter(ImageFilter.DETAIL)
        except ValueError as e:
            tkinter.messagebox.showerror('错误',repr(e))
        return img
    if path != '':
        try:
            img = Image.open(path)
            img=function(img)
            img = img.resize((x, y), Image.ANTIALIAS)
            img_n = img.resize((180, 180), Image.ANTIALIAS)
            global img_new
            img_new = ImageTk.PhotoImage(img_n)
            label_img2.configure(image=img_new)
            label_img2.pack()
            global  output_path,output_file
            output_path=file_path + '\\' + front + '.' + type
            output_file=img

        except OSError:
            lb.config(text="您没有选择任何文件")
            tkinter.messagebox.showerror('错误', '图片格式错误,无法识别')
    else:
        tkinter.messagebox.showerror('错误', '未发现路径')
#确定
def output():
    global output_file,output_path
    output_file.save(output_path,quality=quality)

回调函数之间,应该利用全局变量来通信,而不是协程、生成器对象(我知道你们像这么做,但是不可能的)。
以下为功能测试:测试图

写道最后,应用程序打包

如果我们的文件,一直是什么.py格式的话,相信也不会有人愿意用它。
现在我们尝试走一遍python应用程序的打包,打开cmd,输入:

pyinstaller -Fw 图片格式转换.py

cmd
文件
会生成dist文件夹,打开一看,正常是正常,但是文件大小不可描述…

这就是不用虚拟环境的坏处,pyinstaller把我的aconda所有库给塞进去了。

现在我们来安装虚拟环境吧。
安装pipenv

 pip install pipenv   

在干净目录下初始化python环境, 系统会自动在环境变量里搜索符合要求的python环境

pipenv --python 3.6

进入虚拟环境(第一次进入会自动进行安装 pipenv install)

pipenv shell

pip install pillow
pip install tkinter
pyinstaller -Fw 图片格式转换.py

大功告成

ok,大功告成,源码我会放在github上:https://github.com/ivat4u/Black-Technology
喜欢的朋友务必点个star哦,有什么更好的建议可以直接m我。

  • 3
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值