如何做jquery音乐网站,互联网营销推广服务商,北京工业产品设计公司,网站搜索栏怎么做【相关学习推荐#xff1a;python教程】文章目录前言Github效果实现过程整体代码前言看电影的时候发现一个照片墙的功能#xff0c;觉得这样生成照片挺好玩的#xff0c;于是就动手用Python做了一下#xff0c;觉得用来作照片纪念的效果可能会不错。P:后面了解到我想做的功…【相关学习推荐python教程】文章目录前言Github效果实现过程整体代码前言看电影的时候发现一个照片墙的功能觉得这样生成照片挺好玩的于是就动手用Python做了一下觉得用来作照片纪念的效果可能会不错。P:后面了解到我想做的功能叫蒙太奇拼图所以这篇博客记录先留着闲下来会去看一下蒙太奇拼图的算法Githubhttps://github.com/jiandi1027/photo.git效果实现过程1.获取图片文件夹的图片个数N将底图拆分成XY块区域且使X * Y(为了保证整体的协调会舍弃几张图片比如5张时可能只取22的4张图片)# 打开图片base Image.open(baseImgPath)base base.convert(RGBA)# 获取图片文件夹图片并打乱顺序files glob.glob(imagesPath /*.*)random.shuffle(files)# 图片数量num len(files)# 底图大小x base.size[0]y base.size[1]# 每张图片数量 这个公式是为了xNum * yNum 的总图片数量yNum int((num / (y / x)) ** 0.5)if yNum 0:yNum 1xNum int(num / yNum)# 图片大小 因为像素没有小数点 为防止黑边所以1xSize int(x / xNum) 1ySize int(y / yNum) 12.遍历文件夹的图片依次填充生成最终合成图for file in files:fromImage Image.open(file)i int(num % xNum)j int(num / xNum)out fromImage.resize((xSize, ySize), Image.ANTIALIAS).convert(RGBA)toImage.paste(out, (i * xSize, j * ySize))toImage toImage.convert(RGBA)img Image.blend(base, toImage, 0.3)# 显示图片photo ImageTk.PhotoImage(img)showLabel.config(imagephoto)showLabel.image photoif num xNum * yNum:num num 13.生成结束后保存图片toImage.save(‘generator.png’)img.save(“final.png”)4.建立可视化界面5.Pyinstaller生成exe可执行文件安装pyinstaller模块执行命令生成exe文件pyinstaller -F -w test.py (-w就是取消窗口)整体代码Python的语法和设计规范还没学过所以代码规范代码复用之类的可能会有点不到位本博文主要是一个思路与整体流程的记录。后续又优化了一下一些特效比如合成图片采用随机位置增加黑白流年等显示特效透明度自选等。import PIL.Image as Imageimport globimport randomimport tkinter.filedialogfrom tkinter.filedialog import askdirectory, Label, Button, Radiobutton, Entryimport threadingimport numpy as npfrom PIL import ImageTkalpha 0.3imagesPath # 滑动条回调 修改透明度def resize(evNone):global alphaalpha scale.get() / 100# 黑白def blackWithe(image):# r,g,b r*0.299g*0.587b*0.114im np.asarray(image.convert(RGB))trans np.array([[0.299, 0.587, 0.114], [0.299, 0.587, 0.114], [0.299, 0.587, 0.114]]).transpose()im np.dot(im, trans)return Image.fromarray(np.array(im).astype(uint8))# 流年def fleeting(image, params12):im np.asarray(image.convert(RGB))im1 np.sqrt(im * [1.0, 0.0, 0.0]) * paramsim2 im * [0.0, 1.0, 1.0]im im1 im2return Image.fromarray(np.array(im).astype(uint8))# 旧电影def oldFilm(image):im np.asarray(image.convert(RGB))# rr*0.393g*0.769b*0.189 gr*0.349g*0.686b*0.168 br*0.272g*0.534b*0.131trans np.array([[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]]).transpose()# clip 超过255的颜色置为255im np.dot(im, trans).clip(max255)return Image.fromarray(np.array(im).astype(uint8))# 反色def reverse(image):im 255 - np.asarray(image.convert(RGB))return Image.fromarray(np.array(im).astype(uint8))def chooseBaseImagePath():name tkinter.filedialog.askopenfilename()if name ! :global baseImgPathbaseImgPath namebaseImageLabel.config(textname)baseImg Image.open(baseImgPath)widthEntry.delete(0, tkinter.END)heightEntry.delete(0, tkinter.END)widthEntry.insert(0, baseImg.size[0])heightEntry.insert(0, baseImg.size[1])else:baseImageLabel.config(text您没有选择任何文件)def chooseImagesPath():name askdirectory()if name ! :global imagesPathimagesPath nameImagesLabel.config(textname)else:ImagesLabel.config(text您没有选择任何文件)def thread_it(func, *args):# 创建t threading.Thread(targetfunc, argsargs)# 守护 !!!t.setDaemon(True)# 启动t.start()def test():MyThread(1, Thread-1, 1).start()baseImgPath def generator():baseImg Image.open(baseImgPath)baseImg baseImg.convert(RGBA)files glob.glob(imagesPath /*.*) # 获取图片random.shuffle(files)num len(files)# 模板图片大小x baseImg.size[0]y baseImg.size[1]# 每张图片数量 这个公式是为了xNum * yNum 的总图片数量yNum int((num / (y / x)) ** 0.5)if yNum 0:yNum 1xNum int(num / yNum)# 图片大小 因为像素没有小数点 为防止黑边所以1xSize int(x / xNum) 1ySize int(y / yNum) 1# 生成数量的随机列表 用于随机位置合成图片l [n for n in range(0, xNum * yNum)]random.shuffle(l)toImage Image.new(RGB, (x, y))num 1for file in files:if num xNum * yNum:num num 1else:breakfromImage Image.open(file)temp l.pop()i int(temp % xNum)j int(temp / xNum)out fromImage.resize((xSize, ySize), Image.ANTIALIAS).convert(RGBA)toImage.paste(out, (i * xSize, j * ySize))toImage toImage.convert(RGBA)img Image.blend(baseImg, toImage, alpha)# 特效 但是会读取像素会降低效率choose v.get()if choose 1:img blackWithe(img)elif choose 2:img fleeting(img)elif choose 3:img oldFilm(img)elif choose 4:img reverse(img)resize img.resize((300, 300), Image.ANTIALIAS).convert(RGBA)# 显示图片photo ImageTk.PhotoImage(resize)showLabel.config(imagephoto)showLabel.image phototoImage.save(generator.png)img img.resize((int(widthEntry.get()),int(heightEntry.get())), Image.ANTIALIAS).convert(RGBA)img.save(final.png)resize.save(resize.png)class MyThread(threading.Thread): # 继承父类threading.Threaddef __init__(self, threadID, name, counter):threading.Thread.__init__(self)self.threadID threadIDself.name nameself.counter counterdef run(self): # 把要执行的代码写到run函数里面 线程在创建后会直接运行run函数generator()root tkinter.Tk()root.title(generator)root.geometry(500x550)baseImageLabel Label(root, text)baseImageLabel.place(x10, y10)baseImageBtn Button(root, text选择底图, commandchooseBaseImagePath).place(x10, y30)ImagesLabel Label(root, text)ImagesLabel.place(x10, y60)ImagesBtn Button(root, text选择合成图文件夹, commandchooseImagesPath).place(x10, y80)v tkinter.IntVar()v.set(0)Radiobutton(root, variablev, text默认, value0, ).place(x10, y120)Radiobutton(root, variablev, text黑白, value1, ).place(x110, y120)Radiobutton(root, variablev, text流年, value2, ).place(x210, y120)Radiobutton(root, variablev, text旧电影, value3, ).place(x310, y120)Radiobutton(root, variablev, text反色, value4, ).place(x410, y120)scaleLabel Label(root, text透明度).place(x10, y170)scale tkinter.Scale(root, from_0, to100, orienttkinter.HORIZONTAL, commandresize)scale.set(30) # 设置初始值scale.pack(filltkinter.X, expand1)scale.place(x70, y150)Label(root, text宽(像素)).place(x180, y170)widthEntry Entry(root, bd1)widthEntry.place(x230, y173, width100)Label(root, text高(像素)).place(x320, y170)heightEntry Entry(root, bd1)heightEntry.place(x370, y173, width100)generatorBtn Button(root, text生成, commandtest).place(x10, y220)showLabel Label(root)showLabel.place(x100, y220)root.mainloop()想了解更多编程学习敬请关注php培训栏目