介绍
在这个项目中,我们将使用 Python 和 Tkinter 创建一个图像查看器应用程序。该图像查看器将允许你打开图像文件、显示图像,并执行诸如放大、缩小和旋转图像等操作。我们将使用 PIL(Python Imaging Library)库来处理图像操作,并使用 Tkinter 创建图形用户界面。
👀 预览

🎯 任务
在这个项目中,你将学习:
- 如何使用 Tkinter 创建 GUI 应用程序。
- 如何使用 PIL 处理图像加载和显示。
- 如何为显示的图像实现放大、缩小和旋转功能。
🏆 成果
完成这个项目后,你将能够:
- 使用 Python 和 Tkinter 开发一个功能齐全的图像查看器应用程序。
- 使用 PIL 库集成图像处理功能。
- 实现诸如缩放和旋转等基本图像操作功能。
创建项目文件
首先,创建一个名为 ~/project/image_viewer.py 的新文件,并在文本编辑器或集成开发环境(IDE)中打开它。
cd ~/project
touch image_viewer.py
导入所需的库
在 image_viewer.py 文件中,导入必要的库:
import tkinter as tk
from tkinter import filedialog
from tkinter import messagebox
from PIL import Image, ImageTk
import os
tkinter 库提供创建图形用户界面元素的功能,filedialog 允许我们打开文件对话框以选择图像文件,messagebox 用于向用户显示消息,PIL 用于图像处理,os 提供与操作系统交互的函数。
创建 ImageViewer 类
定义一个名为 ImageViewer 的新类,用于处理图像查看器应用程序:
class ImageViewer:
def __init__(self, root):
self.root = root
self.root.title('LabEx 图像查看器')
self.root.geometry('800x600')
self.root.configure(background='白色')
self.image_label = tk.Label(self.root)
self.image_label.pack()
self.control_frame = tk.Frame(self.root)
self.control_frame.pack()
self.open_button = tk.Button(self.control_frame, text='打开', command=self.open_image)
self.open_button.pack(side='left')
self.close_button = tk.Button(self.control_frame, text='退出', command=self.root.quit)
self.close_button.pack(side='left')
self.zoom_in_button = tk.Button(self.control_frame, text='放大', command=self.zoom_in)
self.zoom_in_button.pack(side='left')
self.zoom_out_button = tk.Button(self.control_frame, text='缩小', command=self.zoom_out)
self.zoom_out_button.pack(side='left')
self.rotate_button = tk.Button(self.control_frame, text='旋转', command=self.rotate)
self.rotate_button.pack(side='left')
self.current_image_path = ''
self.zoom_level = 1
在 __init__ 方法中,我们使用标题、大小和背景颜色初始化根窗口。然后,我们创建一个标签来显示图像,并创建一个框架来容纳控制按钮(打开、退出、放大、缩小、旋转)。我们还定义了实例变量来跟踪当前图像路径和缩放级别。
实现 open_image 方法
向 ImageViewer 类中添加 open_image 方法:
def open_image(self):
self.current_image_path = filedialog.askopenfilename(defaultextension=".jpg",
filetypes=[("所有文件", "*.*"), ("JPEG", ".jpg"), ("PNG", ".png"), ("GIF", ".gif")])
if self.current_image_path:
self.load_image()
open_image 方法会打开一个文件对话框以选择图像文件。它将 current_image_path 变量设置为所选文件的路径,并调用 load_image 方法来显示图像。
实现 load_image 方法
实现 load_image 方法:
def load_image(self):
image = Image.open(self.current_image_path)
## 调整图像大小以进行显示
max_size = (600, 600)
image.thumbnail(max_size)
## 保存对原始图像的引用(用于缩放/旋转)
self.original_image = image
## 创建与 Tkinter 兼容的图像
self.tk_image = ImageTk.PhotoImage(image)
self.image_label.configure(image=self.tk_image)
self.zoom_level = 1
load_image 方法使用 PIL 的 Image.open 方法打开所选图像文件。它使用 thumbnail 方法将图像调整大小以适应最大尺寸为 600x600 像素。然后,它保存对原始图像的引用,以便用于缩放和旋转。接下来,它使用 ImageTk.PhotoImage 创建一个与 Tkinter 兼容的图像,并更新图像标签以显示加载的图像。最后,它将初始缩放级别设置为 1。
实现放大方法
实现 zoom_in 方法:
def zoom_in(self):
if not self.current_image_path: ## 没有加载图像
return
self.zoom_level *= 1.1 ## 将缩放级别提高 10%
self.zoom_or_rotate_image()
zoom_in 方法检查是否加载了图像。如果没有加载图像,它将返回。否则,它会将缩放级别提高 10%,并调用 zoom_or_rotate_image 方法来更新显示的图像。
实现缩小方法
实现 zoom_out 方法:
def zoom_out(self):
if not self.current_image_path: ## 没有加载图像
return
if self.zoom_level < 0.1: ## 限制向外缩放
return
self.zoom_level *= 0.9 ## 将缩放级别降低 10%
self.zoom_or_rotate_image()
zoom_out 方法检查是否加载了图像。如果没有加载图像,它将返回。如果缩放级别已经低于 0.1,这意味着图像已经缩小到极限,它也将返回。否则,它会将缩放级别降低 10%,并调用 zoom_or_rotate_image 方法来更新显示的图像。
实现旋转方法
实现 rotate 方法:
def rotate(self):
if not self.current_image_path: ## 没有加载图像
return
self.original_image = self.original_image.rotate(-90)
self.zoom_or_rotate_image()
rotate 方法检查是否加载了图像。如果没有加载图像,它将返回。否则,它使用 Pillow(PIL)库中的 rotate 方法将原始图像逆时针旋转 90 度,并调用 zoom_or_rotate_image 方法来更新显示的图像。
实现缩放或旋转图像方法
实现 zoom_or_rotate_image 方法:
def zoom_or_rotate_image(self):
## 缩放并旋转原始图像,转换为 Tk 图像,然后显示
new_image = self.original_image.resize((int(self.original_image.width * self.zoom_level),
int(self.original_image.height * self.zoom_level)))
self.tk_image = ImageTk.PhotoImage(new_image)
self.image_label.configure(image=self.tk_image)
zoom_or_rotate_image 方法根据当前缩放级别调整原始图像的大小。它使用 Pillow(PIL)库中的 resize 方法创建一个具有更新后大小的新图像。然后,它使用 ImageTk.PhotoImage 将新图像转换为与 Tkinter 兼容的图像,并更新图像标签以显示更新后的图像。
创建主应用程序循环
在 image_viewer.py 文件末尾添加以下代码以创建主应用程序循环:
if __name__ == '__main__':
root = tk.Tk()
app = ImageViewer(root)
root.mainloop()
这段代码创建了一个 Tkinter 根窗口,初始化了 ImageViewer 类的一个实例,并启动了主应用程序循环。
切换到桌面并运行 image_viewer.py 文件来测试应用程序。你应该会看到以下窗口:
python image_viewer.py

总结
恭喜你!你已经使用 Python 和 Tkinter 创建了一个图像查看器应用程序。该应用程序允许你打开图像文件、显示图像,并执行诸如放大、缩小和旋转图像等操作。你已经学习了如何使用 Pillow(PIL)库进行图像处理以及如何使用 Tkinter 创建图形用户界面。你可以随意进一步自定义该应用程序或探索其他功能。



