日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > php >内容正文

php

python和php合成,Python照片合成的方法详解

發布時間:2025/3/12 php 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python和php合成,Python照片合成的方法详解 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

【相關學習推薦:python教程】

文章目錄前言

Github

效果

實現過程

整體代碼

前言

看電影的時候發現一個照片墻的功能,覺得這樣生成照片挺好玩的,于是就動手用Python做了一下,覺得用來作照片紀念的效果可能會不錯。

P:后面了解到我想做的功能叫蒙太奇拼圖,所以這篇博客記錄先留著,閑下來會去看一下蒙太奇拼圖的算法

Github

https://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 = 1

xNum = int(num / yNum)

# 圖片大小 因為像素沒有小數點 為防止黑邊所以+1

xSize = int(x / xNum) + 1

ySize = int(y / yNum) + 1

2.遍歷文件夾的圖片,依次填充生成最終合成圖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(image=photo)

showLabel.image = photo

if num < xNum * yNum:

num = num + 1

3.生成結束后保存圖片

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 Image

import glob

import random

import tkinter.filedialog

from tkinter.filedialog import askdirectory, Label, Button, Radiobutton, Entry

import threading

import numpy as np

from PIL import ImageTk

alpha = 0.3

imagesPath = ''

# 滑動條回調 修改透明度

def resize(ev=None):

global alpha

alpha = scale.get() / 100

# 黑白

def blackWithe(image):

# r,g,b = r*0.299+g*0.587+b*0.114

im = 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, params=12):

im = np.asarray(image.convert('RGB'))

im1 = np.sqrt(im * [1.0, 0.0, 0.0]) * params

im2 = im * [0.0, 1.0, 1.0]

im = im1 + im2

return Image.fromarray(np.array(im).astype('uint8'))

# 舊電影

def oldFilm(image):

im = np.asarray(image.convert('RGB'))

# r=r*0.393+g*0.769+b*0.189 g=r*0.349+g*0.686+b*0.168 b=r*0.272+g*0.534b*0.131

trans = np.array([[0.393, 0.769, 0.189], [0.349, 0.686, 0.168], [0.272, 0.534, 0.131]]).transpose()

# clip 超過255的顏色置為255

im = np.dot(im, trans).clip(max=255)

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 baseImgPath

baseImgPath = name

baseImageLabel.config(text=name)

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 imagesPath

imagesPath = name

ImagesLabel.config(text=name)

else:

ImagesLabel.config(text="您沒有選擇任何文件")

def thread_it(func, *args):

# 創建

t = threading.Thread(target=func, args=args)

# 守護 !!!

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 = 1

xNum = int(num / yNum)

# 圖片大小 因為像素沒有小數點 為防止黑邊所以+1

xSize = int(x / xNum) + 1

ySize = int(y / yNum) + 1

# 生成數量的隨機列表 用于隨機位置合成圖片

l = [n for n in range(0, xNum * yNum)]

random.shuffle(l)

toImage = Image.new('RGB', (x, y))

num = 1

for file in files:

if num <= xNum * yNum:

num = num + 1

else:

break

fromImage = 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(image=photo)

showLabel.image = photo

toImage.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.Thread

def __init__(self, threadID, name, counter):

threading.Thread.__init__(self)

self.threadID = threadID

self.name = name

self.counter = counter

def run(self): # 把要執行的代碼寫到run函數里面 線程在創建后會直接運行run函數

generator()

root = tkinter.Tk()

root.title('generator')

root.geometry('500x550')

baseImageLabel = Label(root, text='')

baseImageLabel.place(x=10, y=10)

baseImageBtn = Button(root, text="選擇底圖", command=chooseBaseImagePath).place(x=10, y=30)

ImagesLabel = Label(root, text='')

ImagesLabel.place(x=10, y=60)

ImagesBtn = Button(root, text="選擇合成圖文件夾", command=chooseImagesPath).place(x=10, y=80)

v = tkinter.IntVar()

v.set(0)

Radiobutton(root, variable=v, text='默認', value=0, ).place(x=10, y=120)

Radiobutton(root, variable=v, text='黑白', value=1, ).place(x=110, y=120)

Radiobutton(root, variable=v, text='流年', value=2, ).place(x=210, y=120)

Radiobutton(root, variable=v, text='舊電影', value=3, ).place(x=310, y=120)

Radiobutton(root, variable=v, text='反色', value=4, ).place(x=410, y=120)

scaleLabel = Label(root, text='透明度').place(x=10, y=170)

scale = tkinter.Scale(root, from_=0, to=100, orient=tkinter.HORIZONTAL, command=resize)

scale.set(30) # 設置初始值

scale.pack(fill=tkinter.X, expand=1)

scale.place(x=70, y=150)

Label(root, text='寬(像素)').place(x=180, y=170)

widthEntry = Entry(root, bd=1)

widthEntry.place(x=230, y=173, width=100)

Label(root, text='高(像素)').place(x=320, y=170)

heightEntry = Entry(root, bd=1)

heightEntry.place(x=370, y=173, width=100)

generatorBtn = Button(root, text="生成", command=test).place(x=10, y=220)

showLabel = Label(root)

showLabel.place(x=100, y=220)

root.mainloop()想了解更多編程學習,敬請關注php培訓欄目!

創作挑戰賽新人創作獎勵來咯,堅持創作打卡瓜分現金大獎

總結

以上是生活随笔為你收集整理的python和php合成,Python照片合成的方法详解的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。