반응형

 

예전에 C#으로 GUI 버튼 만들고 이미지 삽입해보는 것은 간단하게 경험해본 적이 있지만 파이썬을 통해 인터페이스를 만들어보는 것은 처음이었다. 지인의 부탁을 통해서 한번 도전해봤는데 꽤나 재미있는 작업이었다(지인의 프로그래밍 과제 문의는 누구보다 열심히 도와주는 편,,,,,, ㄷㄷ). 하나부터 열 가지 처음부터 시작했는데 일단 적절한 이미지를 찾는데 시간이 좀 걸렸던 것 같다. 머리스타일, 얼굴형, 코, 입, 피부색까지 하고 싶었지만 적절한 이미지를 찾는데 시간이 너무 오래 걸려 눈썹과 눈만 하기로 결정하였다.

 

<준비물>

그림파일.zip
0.08MB

얼굴판은 jpg 파일이며 눈썹과 눈 모양은 배경이 투명한 png파일이다.

구글에서 이미지들을 캡쳐해서 아래의 사이트에서 배경이 투명한 png파일로 변환 가능하니 참고!
(이 사이트 강추드려요)

www.remove.bg/ko

 

이미지에서 배경 제거 – remove.bg

이미지 배경 제거: 클릭 한 번 없이, 5초만에, 100% 자동, 무료.

www.remove.bg

 

<소스코드>

from tkinter import *
from PIL import ImageTk, Image

eyes = [0,0,0] # 클릭된 눈모양이 몇번인지 체크하는 배열
brows = [0,0,0] # 클릭된 눈썹모양이 몇번인지 체크하는 배열

def add():
    background = Image.open("face.JPG") # 얼굴형 파일 불러오기
    if eyes[0] == 1:
        foreground = Image.open("eye1.png")
    elif eyes[1] == 1:
        foreground = Image.open("eye2.png")
    elif eyes[2] == 1:
        foreground = Image.open("eye3.png")

    if eyes[0] + eyes[1] + eyes[2] == 1: # 눈1~3중에 클릭된게 있다면 background에 해당 eye 붙여넣기
        img_resize = foreground.resize((210, 70)) # 사진크기 조정
        background.paste(img_resize, (65, 150), img_resize) # 얼굴에 덮어쓸 위치에 맞게 임의로 조정한 값

    if brows[0] == 1:
        foreground = Image.open("brow1.png")
    elif brows[1] == 1:
        foreground = Image.open("brow2.png")
    elif brows[2] == 1:
        foreground = Image.open("brow3.png")

    if brows[0] + brows[1] + brows[2] == 1: # 눈썹1~3중에 클릭된게 있다면 background에 해당 brow 붙여넣기
        img_resize = foreground.resize((210, 70)) # 사진크기 조정
        background.paste(img_resize, (65, 120), img_resize) # 얼굴에 덮어쓸 위치에 맞게 임의로 조정한 값

    img = ImageTk.PhotoImage(background)
    canvas.create_image(0, 0, anchor=NW, image=img) # 이미지파일을 보여줄 캔버스 생성

    canvas.grid()
    window.mainloop()

def event1():
    print("눈1을 선택하였습니다.")
    eyes[1] = eyes[2] = 0
    eyes[0] = 1
    add()

def event2():
    print("눈2을 선택하였습니다.")
    eyes[0] = eyes[2] = 0
    eyes[1] = 1
    add()

def event3():
    print("눈3을 선택하였습니다.")
    eyes[0] = eyes[1] = 0
    eyes[2] = 1
    add()

def event4():
    print("눈썹1을 선택하였습니다.")
    brows[1] = brows[2] = 0
    brows[0] = 1
    add()

def event5():
    print("눈썹2을 선택하였습니다.")
    brows[0] = brows[2] = 0
    brows[1] = 1
    add()

def event6():
    print("눈썹3을 선택하였습니다.")
    brows[0] = brows[1] = 0
    brows[2] = 1
    add()

def event7():
    print("프로그램을 종료합니다.")
    window.destroy() # 윈도우 창 종료


print('몽타주 그리기 프로그램을 시작합니다.')
print('화면에 나타나는 눈과 눈썹모양을 선택해주세요.')


window=Tk() # Tk 클래스 객체(window)를 생성
window.title('몽타주 그리기') # 창 제목
window.geometry('900x500') # 창 크기

#====================이미지 파일====================

# 버튼생성
btn1 = Button(window, text='    눈썹1   ', command=event1)
btn2 = Button(window, text='    눈썹2   ', command=event2)
btn3 = Button(window, text='    눈썹3   ', command=event3)
btn4 = Button(window, text='    눈1    ', command=event4)
btn5 = Button(window, text='    눈2    ', command=event5)
btn6 = Button(window, text='    눈3    ', command=event6)
btn7 = Button(window, text='    종료    ', command=event7)

# 버튼위치 지정
btn1.place(x=420, y=150)
btn2.place(x=600, y=150)
btn3.place(x=780, y=150)
btn4.place(x=420, y=400)
btn5.place(x=600, y=400)
btn6.place(x=780, y=400)
btn7.place(x=820, y=470)

# 이미지파일
eye1 = Image.open("eye1.png")
eye2 = Image.open("eye2.png")
eye3 = Image.open("eye3.png")
brow1 = Image.open("brow1.png")
brow2 = Image.open("brow2.png")
brow3 = Image.open("brow3.png")

# 이미지파일 크기변환
eye1_resize=eye1.resize((160,40))
eye2_resize=eye2.resize((160,40))
eye3_resize=eye3.resize((160,40))
brow1_resize=brow1.resize((160,40))
brow2_resize=brow2.resize((160,40))
brow3_resize=brow3.resize((160,40))

# 위젯 공간에 이미지 설정
eye1_resize=ImageTk.PhotoImage(eye1_resize)
eye2_resize=ImageTk.PhotoImage(eye2_resize)
eye3_resize=ImageTk.PhotoImage(eye3_resize)
brow1_resize=ImageTk.PhotoImage(brow1_resize)
brow2_resize=ImageTk.PhotoImage(brow2_resize)
brow3_resize=ImageTk.PhotoImage(brow3_resize)

# 라벨 생성
label1=Label(image=eye1_resize)
label2=Label(image=eye2_resize)
label3=Label(image=eye3_resize)
label4=Label(image=brow1_resize)
label5=Label(image=brow2_resize)
label6=Label(image=brow3_resize)

# 라벨 위치지정
label1.place(x=380, y=50)
label2.place(x=560, y=50)
label3.place(x=740, y=50)
label4.place(x=370, y=300)
label5.place(x=550, y=300)
label6.place(x=730, y=300)

#====================초기 세팅====================
background = Image.open("face.JPG") # 얼굴형 파일 불러오기
canvas = Canvas(window,width=330,height=445,bg='white',bd=2) #(객체,가로크기,세로크기,배경,테두리 굵기)
img=ImageTk.PhotoImage(background)
canvas.create_image(0,0,anchor=NW,image=img) # 이미지파일을 보여줄 캔버스 생성
canvas.grid()

window.mainloop() # 윈도우 창을 윈도우가 종료될 때 까지 실행.


 

<실행결과>

 

 

<설명>

캡쳐사진과 녹화영상에서 보이듯이 사진이 좀 조잡하지만 이러한 프로그램을 만들어봤다는 것에 소소한 보람을 느꼈다. 좋은 이미지 파일만 있다면 좀 더 퀄리티 있는 작업물을 만들 수 있을 것 같다.

from tkinter import *

Tkinter는 Tk GUI 툴킷에 대한 Python 바인딩입니다. Tk GUI 툴킷에 대한 표준 Python 인터페이스이며 사실상의 표준 GUI입니다. Tkinter는 표준 Linux, Microsoft Windows 및 Mac OS X Python 설치에 포함되어 있습니다. -위키백과

즉, tkinter GUI에 대한 표준 Python 인터페이스이며 Window 창을 생성할 수 있다.

 

from PIL import ImageTk, Image

PIL는 Python Imaging Library로, 다양한 이미지 파일 형식을 지원하는 범용 라이브러리이다.

 

eyes = [0,0,0] # 클릭된 눈모양이 몇번인지 체크하는 배열
brows = [0,0,0] # 클릭된 눈썹모양이 몇번인지 체크하는 배열

배열에서 0 값으로 세팅해주고 눈과 눈썹의 배열 원소 값이 1이라면 해당 번호의 이미지가 선택되었다는 것을 의미한다.

 

def add():
    background = Image.open("face.JPG") # 얼굴형 파일 불러오기
    if eyes[0] == 1:
        foreground = Image.open("eye1.png")
    elif eyes[1] == 1:
        foreground = Image.open("eye2.png")
    elif eyes[2] == 1:
        foreground = Image.open("eye3.png")

    if eyes[0] + eyes[1] + eyes[2] == 1: # 눈1~3중에 클릭된게 있다면 background에 해당 eye 붙여넣기
        img_resize = foreground.resize((210, 70)) # 사진크기 조정
        background.paste(img_resize, (65, 150), img_resize) # 얼굴에 덮어쓸 위치에 맞게 임의로 조정한 값

    if brows[0] == 1:
        foreground = Image.open("brow1.png")
    elif brows[1] == 1:
        foreground = Image.open("brow2.png")
    elif brows[2] == 1:
        foreground = Image.open("brow3.png")

    if brows[0] + brows[1] + brows[2] == 1: # 눈썹1~3중에 클릭된게 있다면 background에 해당 brow 붙여넣기
        img_resize = foreground.resize((210, 70)) # 사진크기 조정
        background.paste(img_resize, (65, 120), img_resize) # 얼굴에 덮어쓸 위치에 맞게 임의로 조정한 값

    img = ImageTk.PhotoImage(background)
    canvas.create_image(0, 0, anchor=NW, image=img) # 이미지파일을 보여줄 캔버스 생성

    canvas.grid()
    window.mainloop()

사진들을 합성하는 함수. 먼저 얼굴 판을 불러오고 eyes와 brows배열 원소들을 검사하여 1로 체크된 게 있다면 이미지 합성에 반영하고, 모두 0일 시 그냥 넘어간다.

 

def event1():
    print("눈1을 선택하였습니다.")
    eyes[1] = eyes[2] = 0
    eyes[0] = 1
    add()

def event2():
    print("눈2을 선택하였습니다.")
    eyes[0] = eyes[2] = 0
    eyes[1] = 1
    add()

def event3():
    print("눈3을 선택하였습니다.")
    eyes[0] = eyes[1] = 0
    eyes[2] = 1
    add()

def event4():
    print("눈썹1을 선택하였습니다.")
    brows[1] = brows[2] = 0
    brows[0] = 1
    add()

def event5():
    print("눈썹2을 선택하였습니다.")
    brows[0] = brows[2] = 0
    brows[1] = 1
    add()

def event6():
    print("눈썹3을 선택하였습니다.")
    brows[0] = brows[1] = 0
    brows[2] = 1
    add()

def event7():
    print("프로그램을 종료합니다.")
    window.destroy() # 윈도우 창 종료

각각의 버튼 클릭 이벤트들. 클릭된 버튼이 지정하는 배열 원소를 1로 저장하고 나머지는 모두 0으로 저장한다. 마지막에 event7은 종료 버튼 클릭 시 실행되는 이벤트이며, 윈도 창을 종료시킨다.

 

print('몽타주 그리기 프로그램을 시작합니다.')
print('화면에 나타나는 눈과 눈썹모양을 선택해주세요.')


window=Tk() # Tk 클래스 객체(window)를 생성
window.title('몽타주 그리기') # 창 제목
window.geometry('900x500') # 창 크기

가장 중요한 창 생성하기!

 

#====================이미지 파일====================

# 버튼생성
btn1 = Button(window, text='    눈썹1   ', command=event1)
btn2 = Button(window, text='    눈썹2   ', command=event2)
btn3 = Button(window, text='    눈썹3   ', command=event3)
btn4 = Button(window, text='    눈1    ', command=event4)
btn5 = Button(window, text='    눈2    ', command=event5)
btn6 = Button(window, text='    눈3    ', command=event6)
btn7 = Button(window, text='    종료    ', command=event7)

# 버튼위치 지정
btn1.place(x=420, y=150)
btn2.place(x=600, y=150)
btn3.place(x=780, y=150)
btn4.place(x=420, y=400)
btn5.place(x=600, y=400)
btn6.place(x=780, y=400)
btn7.place(x=820, y=470)

# 이미지파일
eye1 = Image.open("eye1.png")
eye2 = Image.open("eye2.png")
eye3 = Image.open("eye3.png")
brow1 = Image.open("brow1.png")
brow2 = Image.open("brow2.png")
brow3 = Image.open("brow3.png")

# 이미지파일 크기변환
eye1_resize=eye1.resize((160,40))
eye2_resize=eye2.resize((160,40))
eye3_resize=eye3.resize((160,40))
brow1_resize=brow1.resize((160,40))
brow2_resize=brow2.resize((160,40))
brow3_resize=brow3.resize((160,40))

# 위젯 공간에 이미지 설정
eye1_resize=ImageTk.PhotoImage(eye1_resize)
eye2_resize=ImageTk.PhotoImage(eye2_resize)
eye3_resize=ImageTk.PhotoImage(eye3_resize)
brow1_resize=ImageTk.PhotoImage(brow1_resize)
brow2_resize=ImageTk.PhotoImage(brow2_resize)
brow3_resize=ImageTk.PhotoImage(brow3_resize)

# 라벨 생성
label1=Label(image=eye1_resize)
label2=Label(image=eye2_resize)
label3=Label(image=eye3_resize)
label4=Label(image=brow1_resize)
label5=Label(image=brow2_resize)
label6=Label(image=brow3_resize)

# 라벨 위치지정
label1.place(x=380, y=50)
label2.place(x=560, y=50)
label3.place(x=740, y=50)
label4.place(x=370, y=300)
label5.place(x=550, y=300)
label6.place(x=730, y=300)

캔버스의 크기에 맞게 사진들의 크기를 조정하고 배치하는 코드이다. 맨 위에 command 파라미터는 해당 버튼이 클릭될 시 지정된 함수(event)를 호출하게 된다.

 

#====================초기 세팅====================
background = Image.open("face.JPG") # 얼굴형 파일 불러오기
canvas = Canvas(window,width=330,height=445,bg='white',bd=2) #(객체,가로크기,세로크기,배경,테두리 굵기)
img=ImageTk.PhotoImage(background)
canvas.create_image(0,0,anchor=NW,image=img) # 이미지파일을 보여줄 캔버스 생성
canvas.grid()

window.mainloop() # 윈도우 창을 윈도우가 종료될 때 까지 실행.

프로그램 시작 시 해당 캡쳐사진처럼 창을 띄운다.

 

 

 

군대에 있을 때 야간에 몰래 Exel로 윈도 창으로 강화 게임 만들면서 놀았었는데 파이썬으로 이런 작업을 해보니 뭔가 친숙한 느낌도 들고 재밌기도 하였다. 좀 좋은 사진 파일만 있으면 퀄리티 있고 참 좋을 텐데,,,, 찾기도 힘들고 그냥 이쯤에서 마무리!

반응형

+ Recent posts