본문 바로가기
Python/GUI(tkinter)

독학 Python tkinter(GUI) - 16.photoimage(+PIL)

by To올라운더 2023. 11. 14.
반응형

사용자 편의를 위한 기능 구현에 초점이 맞춰진 GUI이지만,

지금까지 배운 GUI의 버튼이나 다른 위젯들은 모두 텍스트로 이루어져 

뭔가 삭막한 느낌을 가졌을 것이다.

 

그래서 오늘은 tkinter내에 이미지를 추가할 수 있는 photoimage에 대해 알아보겠다.

 

1. 준비물

 - 오늘은 준비물이 있다.

 - 바로 GUI에 추가할 이미지 인데, 아무런 이미지를 하나 불러 와도 되고,

   만만한 비단뱀 이미지를 다운 받아도된다.

 

 - 해당 파일의 이름은 'python.png' 이고 경로는 코드를 작성하는 py 와 같은 경로에 있다.

 - 경로가 동일하지 않아도 상관없지만 경로가 다르다면 이후 코드에서 해당 경로도 나타내주어야한다.

 - 준비는 이제 끝났다.

 

2. 코드

 - 코드는 외의로 간단하다. Label을 선언해주고, image 파라미터에 경로만 넣어주면 된다.

 - 같은 경로에 있을 때는 파일명만 적어주면 되지만, 경로가 다르다면 전체 경로를 입력해야 한다.

from tkinter import *

root = Tk()
root.title('To올라운드의 알찬 GUI 강의')

root.geometry("300x500") # 가로 X 세로 / 대문자X 하면 실행안됨

#msb.showinfo('Welcome','안녕하세요. To올라운더와 함께 하는 GUI입니다.')


body_frame = Frame(root, relief='solid', bd=2, background='orange', padx=5, pady=5)
body_frame.pack(fill='both', expand=True)

body_photo_frame = Frame(body_frame)
body_photo_frame.pack(fill='both', expand=True)

photo1 = PhotoImage(file='python.png')

photo1_label = Label(body_photo_frame, image=photo1)
photo1_label.pack()


quit_btn = Button(body_frame, text='종료', command=quit)
quit_btn.pack(fill='x')


root.resizable(False,False) # x너비, y 변경 허용 여부
root.mainloop()

 

 - 그런데, 여기서 약간의 문제가 발생하는데 불러온 이미지의 크기이다.

 - GUI에 불러올 때 이미지 크기를 조절하지 못하다 보니 원하는 사이즈로 넣을 수 없는데,

   이를 해결하기 위해서 PIL 라이브러리를 추가로 사용해야 한다.

 

3. 이미지 크기 수정하여 추가하기

  - 핵심 내용은 1) PIL 라이브러리를 이용해 원본 이미지의 크기를 구한뒤 (18~21라인)

    2) 원하는 크기와의 비율 값을 구한다.(22라인)

    3) 가로와 세로 크기의 비율값을 이용하여 새로운 이미지를 생성하고(24라인)

    4) 생성된 이미지를 tkinter에서 사용가능한 이미지 형태로 변경한다.(25라인)

 

  - 여기서 유의할 점은 24라인의 resize 메서드를 이용할 때 전달되어야 하는 가로, 세로의 pixel의 값이

   정수형으로 전달되어야 한다는 것과 tuple 형태로 전달되어야 한다는 점이다.

from tkinter import *
from PIL import Image, ImageTk

root = Tk()
root.title('To올라운드의 알찬 GUI 강의')

root.geometry("300x500") # 가로 X 세로 / 대문자X 하면 실행안됨

#msb.showinfo('Welcome','안녕하세요. To올라운더와 함께 하는 GUI입니다.')


body_frame = Frame(root, relief='solid', bd=2, background='orange', padx=5, pady=5)
body_frame.pack(fill='both', expand=True)

body_photo_frame = Frame(body_frame)
body_photo_frame.pack(fill='both', expand=True)

photo1_by_pil = Image.open('python.png')
print(photo1_by_pil.size)

photo1_size = photo1_by_pil.size
resize_ratio = (200 / photo1_size[0]) # 가로 크기 200pixel을 입력하려 할 때 비율 값
 
photo1_resize = photo1_by_pil.resize((int(photo1_size[0] * resize_ratio), int(photo1_size[1] * resize_ratio)))
photo1 = ImageTk.PhotoImage(photo1_resize)


photo1_label = Label(body_photo_frame, image=photo1)
photo1_label.pack()


quit_btn = Button(body_frame, text='종료', command=quit)
quit_btn.pack(fill='x')


root.resizable(False,False) # x너비, y 변경 허용 여부
root.mainloop()
반응형

 

 

 - 요령만 알면 Button(버튼)도 Label 처럼 단순 텍스트가 아닌 image 파일로 변환할 수 있다.

from tkinter import *
from PIL import Image, ImageTk

root = Tk()
root.title('To올라운드의 알찬 GUI 강의')

root.geometry("300x500") # 가로 X 세로 / 대문자X 하면 실행안됨

#msb.showinfo('Welcome','안녕하세요. To올라운더와 함께 하는 GUI입니다.')


body_frame = Frame(root, relief='solid', bd=2, background='orange', padx=5, pady=5)
body_frame.pack(fill='both', expand=True)

body_photo_frame = Frame(body_frame)
body_photo_frame.pack(fill='both', expand=True)

photo1_by_pil = Image.open('python.png')
print(photo1_by_pil.size)

photo1_size = photo1_by_pil.size
resize_ratio = (200 / photo1_size[0]) # 가로 크기 200pixel을 입력하려 할 때 비율 값
 
photo1_resize = photo1_by_pil.resize((int(photo1_size[0] * resize_ratio), int(photo1_size[1] * resize_ratio)))
photo1 = ImageTk.PhotoImage(photo1_resize)


photo1_label = Label(body_photo_frame, image=photo1)
photo1_label.pack()

photo2 = PhotoImage(file='byebye.png')
quit_btn = Button(body_frame, image=photo2, command=quit)
quit_btn.pack(fill='x')


root.resizable(False,False) # x너비, y 변경 허용 여부
root.mainloop()

 

반응형