[源代码] 一个简单的PIL+Tk的GIF录屏工具

介绍

只有tkinter和Pillow需要,用Image.save(save_all=1)实现
其实很少人知道,append_images可以传入iter

代码

import os
import time
import tempfile
import tkinter as tk
from tkinter import ttk
import tkinter.filedialog as fd
from PIL import ImageGrab
from PIL import Image
def get_geometry():
    imf.update()
    x = imf.winfo_rootx()
    y = imf.winfo_rooty()
    w = imf.winfo_width()
    h = imf.winfo_height()
    return x,y,w+x,h+y
def start():
    global cam
    if cam:return
    cam = 1
    geo = get_geometry()
    r = root.geometry()
    b1["state"] = "disabled"
    b3["state"] = "disabled"
    path = tempfile.mkdtemp(prefix="SGC_",suffix="TMP")
    start = time.time()
    fmt = path+"/screen_%d.jpg"
    first = ImageGrab.grab(geo)
    leng = 1
    truequality = (1,25,50,75,95)[quality-1]
    #if use resizable,it will flash
    root.minsize(root.winfo_width(),root.winfo_height())
    root.maxsize(root.winfo_width(),root.winfo_height())
    while cam:
        try:ImageGrab.grab(get_geometry()).save(fmt%leng,quality=truequality)
        except:return
        leng += 1
        root.update()
    dur = round((time.time()-start)/(leng),2)
    dur /= speed
    fn = fd.asksaveasfilename(filetypes=(("GIF animate",".gif"),),defaultextension=".gif")
    if not fn:
        for n in getimg(path):
            #to remove temp
            pass
        b1["state"] = "normal"
        b2["state"] = "normal"
        b3["state"] = "normal"
        return
    first.save(fn,save_all=1,append_images=getimg(path),duration=dur,quality=truequality)
    root.minsize(Width,Height)
    root.maxsize(root.winfo_screenwidth(),root.winfo_screenheight())
    b1["state"] = "normal"
    b2["state"] = "normal"
    b3["state"] = "normal"
def end():
    global cam
    if cam:
        b2["state"] = "disabled"
    cam = 0
def getimg(path):
    for name in sorted(os.listdir(path),key=len):
        name = path+"/"+name
        im = Image.open(name)
        im.load()
        os.remove(name)
        root.update()
        yield im
    #os.remove(path)
def about():
    top = tk.Toplevel()
    top.transient(root)
    top.grab_set()
    top.title("About")
    top.resizable(0,0)
    top.focus_set()
    tk.Label(top,font="Arial 20",text="SimpleGIFCam").pack()
    s = tk.Scale(top,orient="horizontal",label="Quality",from_=1,to=5,command=choosequality)
    s.pack()
    s.set(quality)
    s = tk.Scale(top,orient="horizontal",label="Speed",from_=-3,to=3,command=choosespeed)
    s.pack()
    s.set(1)
    root.wait_window(top)
def choosequality(num):
    global quality
    quality = int(num)
def choosespeed(num):
    global speed
    num = int(num)
    speed = (1,1,2,3,0.3,0.5,1)[num]
cam = 0
quality = 3
speed = 1
root = tk.Tk()
root.attributes("-transparentcolor","#fffff0")
root.title("SimpleGIFCam 1.2")
f = tk.Frame(bg="blue",width=300,height=200)
f.pack(fill="both",expand=1)
imf = tk.Frame(f,bg="#fffff0")
imf.place(relx=0.1,rely=0.1,relwidth=0.8,relheight=0.6)
b1 = tk.Button(f,text="Start",command=start)
b1.place(relx=0.1,rely=0.8,relwidth=0.2,relheight=0.18)
b2 = tk.Button(f,text="End",command=end)
b2.place(relx=0.5,rely=0.8,relwidth=0.2,relheight=0.18)
b3 = tk.Button(f,bitmap="questhead",command=about)
b3.place(relx=0.8,rely=0.8,relwidth=0.1,relheight=0.18)
ttk.Style().configure("S.TSizegrip",background="blue")
ttk.Sizegrip(f,style="S.TSizegrip").place(relx=0.9,rely=0.9,relwidth=0.1,relheight=0.1)
for b in (b1,b2,b3):
    b.config(bg="blue",fg="white",borderwidth=1,relief="flat",activebackground="#00ffff",font="TkDefaultFont 16",disabledforeground="black")
root.update()
Width = root.winfo_width()
Height = root.winfo_height()
root.minsize(Width,Height)
root.mainloop()

效果


本文发于CSDN于 2021/12/26 7:39

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值