Python 사진 합성 방법에 대한 자세한 설명

coldplay.xixi
풀어 주다: 2020-08-29 16:26:12
앞으로
3676명이 탐색했습니다.

Python 사진 합성 방법에 대한 자세한 설명

관련 학습 권장사항: python tutorial

문서 디렉토리

      • 서문
      • Github
      • Effect
      • 구현 과정
      • 전체 코드

머리말

영화를 보다가 포토월 기능을 발견했습니다. 이렇게 사진을 생성하는 것이 재미있다고 생각해서 기념사진으로 활용해도 좋을 것 같다는 생각에 파이썬으로 시작하게 되었습니다.

P photo.git

Effect

구현 과정Python 사진 합성 방법에 대한 자세한 설명
1 사진 폴더에 있는 사진 N개를 가져와 기본 이미지를 XPython 사진 합성 방법에 대한 자세한 설명Y 블록으로 분할하고 X * Y로 만듭니다. (전체적인 조화를 보장하기 위해 여러 장의 사진은 삭제됩니다. 예를 들어 사진이 5장이라면 2

2의 사진은 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 的总图片数量<num又成比例的最大整数
    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(&#39;RGBA&#39;)
        toImage.paste(out, (i * xSize, j * ySize))
        toImage = toImage.convert(&#39;RGBA&#39;)
        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. 생성 후 이미지를Python 사진 합성 방법에 대한 자세한 설명Image.save('generator.png')

img.save("final.png")



4에 저장하세요. 시각적 인터페이스
Python 사진 합성 방법에 대한 자세한 설명
5. Pyinstaller는 exe 실행 파일을 생성합니다. ![Python 사진 합성 방법에 대한 자세한 설명](https://img-blog.csdnimg.cn/20190805150649966.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L2NoaWppYW5kaQ==,size_16,color_FFFFFF,t_70pyinstaller 모듈을 설치하고 명령을 실행하여 exe 파일을 생성합니다.

pyinstaller -F -w test.py (-w就是取消窗口)
로그인 후 복사

전체 코드Python 사진 합성 방법에 대한 자세한 설명
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 = &#39;&#39;


# 滑动条回调 修改透明度
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(&#39;RGB&#39;))
    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(&#39;uint8&#39;))


# 流年
def fleeting(image, params=12):
    im = np.asarray(image.convert(&#39;RGB&#39;))
    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(&#39;uint8&#39;))


# 旧电影
def oldFilm(image):
    im = np.asarray(image.convert(&#39;RGB&#39;))
    # 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(&#39;uint8&#39;))


# 反色
def reverse(image):
    im = 255 - np.asarray(image.convert(&#39;RGB&#39;))
    return Image.fromarray(np.array(im).astype(&#39;uint8&#39;))


def chooseBaseImagePath():
    name = tkinter.filedialog.askopenfilename()
    if name != &#39;&#39;:
        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 != &#39;&#39;:
        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 = &#39;&#39;


def generator():
    baseImg = Image.open(baseImgPath)
    baseImg = baseImg.convert(&#39;RGBA&#39;)
    files = glob.glob(imagesPath + &#39;/*.*&#39;)  # 获取图片
    random.shuffle(files)
    num = len(files)
    # 模板图片大小
    x = baseImg.size[0]
    y = baseImg.size[1]
    # 每张图片数量 这个公式是为了xNum * yNum 的总图片数量<num又成比例的最大整数
    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(&#39;RGB&#39;, (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(&#39;RGBA&#39;)
        toImage.paste(out, (i * xSize, j * ySize))
        toImage = toImage.convert(&#39;RGBA&#39;)
        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(&#39;RGBA&#39;)
        # 显示图片
        photo = ImageTk.PhotoImage(resize)
        showLabel.config(image=photo)
        showLabel.image = photo
    toImage.save(&#39;generator.png&#39;)
    img = img.resize((int(widthEntry.get()),int(heightEntry.get())), Image.ANTIALIAS).convert(&#39;RGBA&#39;)
    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(&#39;generator&#39;)
root.geometry(&#39;500x550&#39;)
baseImageLabel = Label(root, text=&#39;&#39;)
baseImageLabel.place(x=10, y=10)
baseImageBtn = Button(root, text="选择底图", command=chooseBaseImagePath).place(x=10, y=30)
ImagesLabel = Label(root, text=&#39;&#39;)
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=&#39;默认&#39;, value=0, ).place(x=10, y=120)
Radiobutton(root, variable=v, text=&#39;黑白&#39;, value=1, ).place(x=110, y=120)
Radiobutton(root, variable=v, text=&#39;流年&#39;, value=2, ).place(x=210, y=120)
Radiobutton(root, variable=v, text=&#39;旧电影&#39;, value=3, ).place(x=310, y=120)
Radiobutton(root, variable=v, text=&#39;反色&#39;, value=4, ).place(x=410, y=120)

scaleLabel = Label(root, text=&#39;透明度&#39;).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=&#39;宽(像素)&#39;).place(x=180, y=170)
widthEntry = Entry(root, bd=1)
widthEntry.place(x=230, y=173, width=100)
Label(root, text=&#39;高(像素)&#39;).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 training
칼럼을 주목해주세요!

위 내용은 Python 사진 합성 방법에 대한 자세한 설명의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

관련 라벨:
원천:csdn.net
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿