tkinter和PIL這兩個庫在python3.x是內(nèi)置的,不需要額外安裝
最近在學習python惩猫,就用python自己寫了一個仿windows的看圖器,在網(wǎng)上搜發(fā)現(xiàn)找不到相關的代碼震鹉,所以決定自己嘗試做了一個易桃「泊迹看圖器要實現(xiàn)如下功能:
- 打開文件夾,找到相應文件
- 圖片可以進行等比例縮放
- 可以瀏覽同目錄下的上一張和下一張圖片
1.用label方法制作看圖器
由于python的tkinter庫只能打開gif文件不能打開jpg等其它文件炭臭,所以這里需要導入PIL庫永脓。tkinter的學習建議參考莫煩的視頻。莫煩tkinter教程鞋仍。講解非常詳細配有簡單案例適合初學者學習常摧。
import tkinter as tk
from PIL import ImageTK,Image
from tkinter import filedialog #獲取文件全路徑
root=tk.Tk() #創(chuàng)建對象
root.title('圖片查看器') #窗口的名稱
root.geometry('400x400') #規(guī)定窗口大小
l=tk.Label(root,text='pictures will show in this place', image=None) #創(chuàng)建一個標簽
l.pack() #放置標簽
def openpicture():
global img
filename=filedialog.askopenfilename() #獲取文件全路徑
img=ImageTk.PhotoImage(Image.open(filename)) #tkinter只能打開gif文件,這里用PIL庫
# 打開jpg格式的文件
l.config(image=img) #用config方法將圖片放置在標簽中
b=kt.Button(root,text='select a picture', command=openpicture) #設置按鈕威创,并給它openpicture命令
b.pack()
tk.mainloop()
我們開看一下運行效果:
點擊選擇按鈕:
選擇一張圖片:
這樣一個簡單的查看器就做完了落午,但是可以看到當圖片的像素太大的時候圖片無法顯示完全,所以需要對程序進行修改讓它能夠按標簽的大小進行縮放肚豺。
但是經(jīng)過我多次測試溃斋,geometry大小設置的是400x400,label標簽大小設置的是300x300吸申,但遺憾的是最后標簽填滿了整個窗口梗劫,猜測的原因可能是geometry和label的單位不同造成的,于是我改變了label的大小截碴,設置為30x300梳侨,但最終標簽仍然充滿了整個窗口,查閱資料沒能解決是什么原因?qū)е逻@一問題
2.用canvas方法制作看圖器
在label方法遇到困難后轉(zhuǎn)向了canvas方法割坠,直接繪制畫布大小。由于每張圖片的尺寸不一樣妒牙,要想將圖片保持原來的長寬比顯示在canvas上需要將圖像進行縮放彼哼。
對函數(shù)進行縮放的方法參照這篇博文
import tkinter as tk
from PIL import ImageTk, Image
from tkinter import filedialog #獲取文件全路徑
root=tk.Tk()
root.title('圖片查看器')
root.geometry('500x500')
canvas=tk.Canvas(root,height=400,width=400) #畫布長款定為400x400
canvas.pack()
def openpicture():
global img
filename=filedialog.askopenfilename() #獲取文件全路徑
image=Image.open(filename) #打開圖片放到image中
w,h=image.size #獲取image的長和寬
mlength=max(w,h) #取最大的一邊作為縮放的基準
mul=400/mlength #縮放倍數(shù)
w1=int(w*mul)
h1=int(h*mul)
re_image=image.resize((w1,h1))
img=ImageTk.PhotoImage(re_image) #在canvas中展示圖片
canvas.create_image(200,200,anchor='center',image=img) #以中小點為錨點
b=tk.Button(root,text='select a picture', command=openpicture) #設置按鈕,并給它openpicture命令
b.pack()
tk.mainloop()
瀏覽上一張和下一張
這里我的思想是:
- 先獲取該文件的完整路徑
- 獲取該文件的上一級路徑
- 獲取該文件的文件名
- 通過os.listdir()獲取該文件夾下的所有文件并生成列表
- 通過列表找到該文件的索引值
- 將索引值+1湘今,-1實現(xiàn)上一張敢朱,下一張的功能
思想很簡單,在這里我將之前得分代碼重新整理摩瞎,把不同功能進行了封裝
import tkinter as tk
from PIL import ImageTk,Image
from tkinter import filedialog
import os
root=tk.Tk()
root.title('圖片查看器')
root.geometry('500x500')
canvas=tk.Canvas(root,height=400,width=400)
canvas.pack()
path=tk.StringVar()
def resize(image):
w, h = image.size
mlength = max(w, h) # 找出最大的邊
mul = 400 / mlength # 縮放倍數(shù)
w1 = int(w * mul) # 重新獲得高和寬
h1 = int(h * mul)
return image.resize((w1, h1))
def show_image(path):
global img #要申明全局變量我猜測是調(diào)用了canvas
image = Image.open(path) # 打開圖片
re_image = resize(image) # 調(diào)用函數(shù)
img = ImageTk.PhotoImage(re_image) # PhotoImage類是用來在label和canvas展示圖片用的
canvas.create_image(200, 200, anchor='center', image=img)
def openpicture():
#打開一張圖片并顯示
global fileindex,fatherpath,files,file_num
filepath=filedialog.askopenfilename()
fatherpath=os.path.dirname(filepath) #獲取該路徑的上一級路徑
filename=os.path.basename(filepath) #獲取該路徑下的文件名
files=os.listdir(fatherpath) #該路徑下的所有文件并生成列表
file_num=len(files)
fileindex=files.index(filename) #獲取當前文件的索引值
show_image(filepath)
def previous():
global fileindex, fatherpath, files,file_num
fileindex -=1
if fileindex == -1:
fileindex = file_num-1
filepath1=os.path.join(fatherpath, files[fileindex])
show_image(filepath1)
def back():
global fileindex, fatherpath, files,file_num
fileindex += 1
if fileindex == file_num:
fileindex = 0
filepath2 = os.path.join(fatherpath, files[fileindex])
show_image(filepath2)
b=tk.Button(root,text='select a picture',command=openpicture)
b.pack()
b1=tk.Button(root,text='上一張',command=previous).pack(side='left')
b2=tk.Button(root,text='下一張',command=back).pack(side='right')
tk.mainloop()