突发奇想用半天做的一个小工具,试了试还行,就是有点卡from tkinter import Tk import tkinter.messagebox from tkinter import * from tkinter import filedialog from PIL import Image,ImageDraw import imageio import numpy as np import time def main(): def start(): def checkOk(): valuechoice.get() if value1: width150 height100 elif value2: width200 height200 elif value3: width300 height240 elif value4: width400 height360 else: tkinter.messagebox.showerror(error,未选择绘画板大小) return ##获取大小值 root.destroy()#销毁初始窗口 paint(width,height)#打开绘画窗口 ##选择完毕 rootTk() root.title(GC动画制作工具) root.geometry(300x300) try: root.iconbitmap(icon.ico)#设置图标 except Exception: pass sizeLabelLabel(root,text请选择绘画板大小,font(微软雅黑,15)) choicetkinter.IntVar() ##要绑定的布尔类型 check1Radiobutton(root,text150x100,font(微软雅黑,13),variablechoice,value1) check2Radiobutton(root,text250x200,font(微软雅黑,13),variablechoice,value2) check3Radiobutton(root,text300x300,font(微软雅黑,13),variablechoice,value3) check4Radiobutton(root,text500x400,font(微软雅黑,13),variablechoice,value4) choice.set(2)#默认勾选 ##大小选择 okButton(root,text开始绘图,font(微软雅黑,16),commandcheckOk) sizeLabel.pack() check1.pack() check2.pack() check3.pack() check4.pack() ok.pack() root.mainloop() ##开始界面 def paint(width,height): rootTk() root.title(GC动画制作工具) root.geometry(%dx%d%(int(width300),int(height200))) root.resizable(False,False)#锁定窗口 try: root.iconbitmap(icon.ico)#设置图标 except Exception: pass allPage0#总页面数 nowPage0#当前页面 colorblack#默认画笔颜色 bgColorwhite#默认背景颜色 canvasNone#当前画布 pixels[]#当前页面的像素列表 pages[]#存储所有页面数据 pixelSize5#像素大小 def updatePageLabel(): pageLabel.config(text%d/%d页%(nowPage1,allPage)) ##更新页数显示 def saveCurrentPage(): if canvas and pixels: colors[] for pixel in pixels: colors.append(canvas.itemcget(pixel,fill)) return {colors:colors,bgColor:bgColor} return None ##保存当前页面数据 def loadPage(pageData): nonlocal pixels,bgColor if not pageData: return colorspageData[colors] bgColorpageData[bgColor] #清空并重新绘制所有像素 pixels[] canvas.delete(all)#清空画布 for i in range(width * height): rowi//width coli%width x1col*pixelSize y1row*pixelSize x2x1pixelSize y2y1pixelSize pixel canvas.create_rectangle(x1, y1, x2, y2, fillcolors[i] if i len(colors) else bgColor, outline) pixels.append(pixel) ##加载数据到当前画布 def painted(canvas,pixels,idx): canvas.itemconfig(pixels[idx],fillcolor)#切换颜色 def toLast(): nonlocal nowPage if nowPage0: pages[nowPage]saveCurrentPage()#保存当前页 nowPagenowPage-1 loadPage(pages[nowPage])#切换到上一页 updatePageLabel() ##去上一页 def toNext(): nonlocal nowPage if nowPageallPage-1: pages[nowPage]saveCurrentPage()#保存当前页 nowPagenowPage1 loadPage(pages[nowPage])#切换到下一页 updatePageLabel() ##去下一页 def RGB(r,g,b): return f#{int(r):02x}{int(g):02x}{int(b):02x} ##RGB函数 def changeColor(): nonlocal color def updateColorDisplay(): redint(redEntry.get()) greenint(greenEntry.get()) blueint(blueEntry.get()) if red0: red0 if red255: red255 if green0: green0 if green255: green255 if blue0: blue0 if blue255: blue255 displayColorRGB(red,green,blue)#更新展示颜色 colorLabel.configure(backgrounddisplayColor)#刷新显示展示颜色 def finishColor(): nonlocal color redint(redEntry.get()) greenint(greenEntry.get()) blueint(blueEntry.get()) if red0: red0 if red255: red255 if green0: green0 if green255: green255 if blue0: blue0 if blue255: blue255 colorRGB(red,green,blue)#更新画笔颜色 paintColor.configure(backgroundcolor)#更新主窗口画笔颜色 colorWindow.destroy()#销毁子窗口 colorWindowToplevel() colorWindow.title(画笔颜色) colorWindow.geometry(300x300) displayColorcolor colorLabelLabel(colorWindow,bd0,backgrounddisplayColor)#画笔颜色展示 redLabelLabel(colorWindow,textR,font(微软雅黑,12)) redEntrySpinbox(colorWindow,from_0,to255,font(微软雅黑,12)) greenLabelLabel(colorWindow,textG,font(微软雅黑,12)) greenEntrySpinbox(colorWindow,from_0,to255,font(微软雅黑,12)) blueLabelLabel(colorWindow,textB,font(微软雅黑,12)) blueEntrySpinbox(colorWindow,from_0,to255,font(微软雅黑,12)) ##RGB颜色调整 refreshButtonButton(colorWindow,text刷新,font(微软雅黑,15),commandupdateColorDisplay)#刷新显示按钮 finishButtonButton(colorWindow,text完成,font(微软雅黑,15),commandfinishColor)#完成按钮 colorLabel.place(x20,y100,width30,height30) redLabel.place(x100,y20) redEntry.place(x100,y50,width50,height30) greenLabel.place(x100,y80) greenEntry.place(x100,y110,width50,height30) blueLabel.place(x100,y140) blueEntry.place(x100,y170,width50,height30) refreshButton.place(x200,y60) finishButton.place(x200,y150) ##改变画笔颜色 def changeBgColor(): nonlocal bgColor def updateBgDisplay(): redint(redEntry.get()) greenint(greenEntry.get()) blueint(blueEntry.get()) if red0: red0 if red255: red255 if green0: green0 if green255: green255 if blue0: blue0 if blue255: blue255 displayColorRGB(red,green,blue)#更新展示颜色 bgLabel.configure(backgrounddisplayColor)#刷新显示展示颜色 def finishBgColor(): nonlocal bgColor redint(redEntry.get()) greenint(greenEntry.get()) blueint(blueEntry.get()) if red0: red0 if red255: red255 if green0: green0 if green255: green255 if blue0: blue0 if blue255: blue255 bgColorRGB(red,green,blue)#更新背景颜色 backgroundColor.configure(backgroundbgColor)#更新主窗口背景颜色 for pixel in pixels: canvas.itemconfig(pixel,fillbgColor)#更新当前画布背景色像素 bgWindow.destroy()#销毁子窗口 bgWindowToplevel() bgWindow.title(背景颜色) bgWindow.geometry(300x300) displayColorbgColor bgLabelLabel(bgWindow,bd0,backgrounddisplayColor)#背景颜色展示 redLabelLabel(bgWindow,textR,font(微软雅黑,12)) redEntrySpinbox(bgWindow,from_0,to255,font(微软雅黑,12)) greenLabelLabel(bgWindow,textG,font(微软雅黑,12)) greenEntrySpinbox(bgWindow,from_0,to255,font(微软雅黑,12)) blueLabelLabel(bgWindow,textB,font(微软雅黑,12)) blueEntrySpinbox(bgWindow,from_0,to255,font(微软雅黑,12)) ##RGB颜色调整 refreshButtonButton(bgWindow,text刷新,font(微软雅黑,15),commandupdateBgDisplay)#刷新显示按钮 finishButtonButton(bgWindow,text完成,font(微软雅黑,15),commandfinishBgColor)#完成按钮 tipLabel(bgWindow,text小提示:更换背景色会\n覆盖当前画页内容,font(微软雅黑,8)) bgLabel.place(x20,y100,width30,height30) redLabel.place(x100,y20) redEntry.place(x100,y50,width40,height30) greenLabel.place(x100,y80) greenEntry.place(x100,y110,width40,height30) blueLabel.place(x100,y140) blueEntry.place(x100,y170,width40,height30) refreshButton.place(x200,y60) finishButton.place(x200,y150) tip.place(x180,y210) ##改变背景颜色 def createNewPage(): nonlocal nowPage,allPage,canvas,pixels,bgColor def getPixelIndex(event): xevent.x//pixelSize yevent.y//pixelSize if 0xwidth and 0yheight:#如果点击位置在画布里面 return y*widthx return -1 ##获取像素索引 def startDraw(event): idxgetPixelIndex(event)#获取像素索引 if idx!-1: painted(canvas,pixels,idx) ##鼠标按下 def draw(event): idxgetPixelIndex(event)#获取像素索引 if idx!-1: painted(canvas,pixels,idx) ##鼠标拖拽 if canvas and pixels and allPage0: pages[nowPage]saveCurrentPage()#如果当前页不是第一页,保存当前页 canvasCanvas(root,widthwidth,heightheight)#创建画布 canvas.place(x20,y50) canvas.bind(Button-1,startDraw)#绑定鼠标左键 canvas.bind(B1-Motion,draw)#绑定左键移动 pixels[] colors[] for i in range(width*height):#循环次数由图片大小决定 rowi//width coli%width x1col*pixelSize y1row*pixelSize x2x1pixelSize y2y1pixelSize ##坐标 pixelcanvas.create_rectangle(x1,y1,x2,y2,fillbgColor,outline)#创建像素点 pixels.append(pixel) colors.append(bgColor) allPage1 nowPageallPage-1 pages.append({colors: colors, bgColor: bgColor}) updatePageLabel() ##创建新一页 def deletePage(): nonlocal allPage, nowPage if allPage 1: return # 至少保留一页 # 删除当前页 del pages[nowPage] allPage-1 if nowPageallPage: nowPageallPage-1 # 加载新页面 loadPage(pages[nowPage]) updatePageLabel() def saveVideo(filename,fps10): if not pages: tkinter.messagebox.showinfo(error,你还没有画画) return frames[] for page in pages: imgImage.new(RGB,(width*pixelSize,height*pixelSize),page[bgColor]) drawImageDraw.Draw(img) colorspage[colors] for i,col in enumerate(colors): rowi//width colIdxi%width x1colIdx*pixelSize y1row*pixelSize draw.rectangle([x1,y1,x1pixelSize,y1pixelSize],fillcol) frames.append(np.array(img)) with imageio.get_writer(filename, fpsfps) as writer: for frame in frames: writer.append_data(frame) ##保存为视频 numint(time.time())#反覆盖文件名基数 def saveAvi(): nonlocal num saveVideo(%d.avi%(num),fps10) numnum1 tkinter.messagebox.showinfo(success,保存成功) ##保存为avi文件 def saveMp4(): nonlocal num saveVideo(%d.mp4%(num),fps10) numnum1 tkinter.messagebox.showinfo(success,保存成功) ##保存为mp4文件 def toSaveAvi(): nonlocal num filenametkinter.filedialog.asksaveasfilename(defaultextension.avi,title另存为)#另存为文件对话框 if filename: saveVideo(filename,fps10) numnum1 tkinter.messagebox.showinfo(success,保存成功) ##另存为avi文件 def toSaveMp4(): nonlocal num filenametkinter.filedialog.asksaveasfilename(defaultextension.mp4,title另存为)#另存为文件对话框 if filename: saveVideo(filename,fps10) numnum1 tkinter.messagebox.showinfo(success,保存成功) ##另存为mp4文件 def about(): tkinter.messagebox.showinfo(关于,作者:hhcgchpspk) ##关于 lastPageButton(root,text◀,bd0,font(微软雅黑,10),commandtoLast)#上一页 nextPageButton(root,text▶,bd0,font(微软雅黑,10),commandtoNext)#下一页 pageLabelLabel(root,text%d/%d页%(nowPage1,allPage))#页数显示 paintColorLabelLabel(root,text画笔颜色,font(微软雅黑,10)) paintColorButton(root,backgroundcolor,bd0,commandchangeColor)#画笔颜色 backgroundColorLabelLabel(root,text背景颜色,font(微软雅黑,10)) backgroundColorButton(root,backgroundbgColor,bd0,commandchangeBgColor)#背景颜色 newPaintPageButton(root,text画新的一张,font(微软雅黑,15),commandcreateNewPage)#创建新的一张画布按钮 lastPage.place(x20,y10) nextPage.place(x100,y10) pageLabel.place(x50,y13) paintColorLabel.place(x20,yheight100) paintColor.place(x80,yheight100,width20,height20) backgroundColorLabel.place(x120,yheight100) backgroundColor.place(x180,yheight100,width20,height20) newPaintPage.place(x250,yheight100) menuMenu(root)#创建菜单对象 menuFileMenu(menu,tearoffFalse)#tearoff意思为能从窗口分离 menuOperateMenu(menu,tearoffFalse) menu.add_cascade(label文件,menumenuFile) menuFile.add_command(label创建新一页,commandcreateNewPage) menuFile.add_command(label上一页,commandtoLast) menuFile.add_command(label下一页,commandtoNext) menuFile.add_command(label删除本页,commanddeletePage) menuFile.add_command(label保存为.avi,commandsaveAvi) menuFile.add_command(label保存为.mp4,commandsaveMp4) menuFile.add_command(label另存为.avi,commandtoSaveAvi) menuFile.add_command(label另存为.mp4,commandtoSaveMp4) menu.add_cascade(label操作,menumenuOperate) menuOperate.add_command(label更换画笔颜色,commandchangeColor) menuOperate.add_command(label更换背景颜色,commandchangeBgColor) menu.add_command(label关于,commandabout) root.config(menumenu) ##菜单功能 createNewPage()#创建第一页 root.mainloop() ##绘画界面 start() if __name____main__: main()能画成这样本文链接:GC动画制作工具