본문 바로가기
카테고리 없음

Tkinter Canvas 이미지 처리 - 001

by The Programmer 2025. 3. 19.

1. Introduction

 

이 예제는 Tkinter 모듈 Canvas에서 이미지를 나타내고 관련된 이런 저런 처리 방법을 다루고 있습니다. 외부 모듈로 필로우pillow를 사용하고 있기 때문에 이 모듈이 없다면 설치해야 합니다. 

 

pip install pillow

 

설치 시 관련 문제가 발생한다면 아래 Notes의 '기타 사항' 항목을 참고하세요.

( 이 글은 아직 편집중입니다. ^.^;)

 

 

2. Code

 

더보기

# Tkinter Canvas 이미지 처리 - 001

 

import tkinter as tk
from PIL import Image, ImageTk  # 이미지 처리를 위해 PIL(Pillow) 라이브러리 사용

# Tkinter 윈도우 생성
tkWindow1 = tk.Tk()
# Root 윈도우 배경색 설정 (예: lightyellow, lightblue==#ADD8E6 )
# 테두리가 나타나지 않으면 relief 옵션 추가해야함.
# "flat": 기본값(테두리 없음) "solid": 단색 테두리 "raised": 양각 테두리 "sunken": 음각 테두리
# "ridge": 돌출 테두리 "groove": 홈 테두리
tkWindow1.config(bg="gray", highlightcolor="lightblue", highlightthickness=15, relief="solid")
tkWindow1.geometry("1024x800+200+200")
tkWindow1.title("Canvas에 이미지 표시하기")
# 참고 : config메서드 옵션, highlightbackground="lightgray" , highlightcolor="lightgray"

"""
# tkinter root 윈도우의 배경색을 지정하는 다른 방법.
# Frame 생성 (배경색: lightyellow)
frame = tk.Frame(root, bg="lightyellow")
frame.pack(fill="both", expand=True)  # 윈도우 전체를 채우도록 배치
이후의 위젯들은 frame에 배치해야 한다.
root 윈도우의 테두리 배경색 지정이 잘 안 되면 프레임을 사용해야 하는 듯.
약간의 편법으로 하이라이트 색상 지정은 되는 듯. 두께 필요.
tkWindow1.config(bg="gray", highlightcolor="lightblue", highlightthickness=15, relief="solid")
실제로는 색상과 두께를 좀 더 세밀하게 조정해서 사용해야 함.
컬러는 웹컬러 표기법 지원 : #RRGGBB, #6699FF 처럼. 가능.
"""

# Canvas 위젯 생성 (배경색: lightblue)
canvas = tk.Canvas(tkWindow1, width=860, height=640, bg="lightblue")
# canvas의 외부 여백 추가
canvas.pack(padx=40, pady=40)

"""
# canvas의 외부 여백 추가 다른 방법 :
# place() 메서드 방법.
# canvas.place(x=20, y=20)    #
"""

# 외부 이미지 파일 로드
image_path = "data/pic000_.png" 

# 표시하려는 이미지 파일 경로, like Processing v4.3.4. data 폴더에 이미지 저장.

# 메인 소스코드 파일인 ~~.py의 위치를 기준으로 그 하위 폴더로 data  폴더를 만들고

# 그곳에 pic000_.png 파일 저장.

image = Image.open(image_path)  # 이미지 열기
image = image.resize((400, 400))  # Canvas 크기에 맞게 이미지 크기 조정 (선택 사항)

# 위 두 줄은 단일 명령 체인으로 합치기도 가능, 코드 가독성 때문에 풀어서 진행함.
# image = Image.open(image_path).resize((400, 400))


tk_image = ImageTk.PhotoImage(image)

# Canvas에 이미지 표시
canvas.create_image(40, 40, anchor=tk.NW, image=tk_image)

# Tkinter 메인 루프 실행
tkWindow1.mainloop()

 

# EOF(=END of File).

 

 

3. Result

 

[ Tkinter.Canvas에 외부 이미지 표시하기 - 1 ]

 

4. Notes

약간의 추가 설명. ^.^;

 

 전체적 절차 

 

1) tkinter, PIL 등 필요한 외부 모듈을 불러오고

2) tkinter root 윈도우를 만들고

3) tkinter.canvas를 만들고

4) 외부 이미지 파일 정보를 불러오고

5) 이 정보를 이용해서 이미지 파일을 실제로 열고, 크기를 재조정한 다음

6) 재조정된 파일을 ImageTk 모듈의 확장판 포토이미지로 변환한다.

7) 이 tkinter 포토이미지를 이용해서 캔버스에 실제로 이미지를 나타낸다(create).

8) tkinter root 윈도우 메인 루프 작동시키기.

 

 

1) 단계 : tkinter, PIL 등 필요한 외부 모듈을 불러오고

■ Tkinter 모듈 불러오기와 귀찮은 긴 이름 대신에 별명 사용하기

 

import tkinter as tk

 

모듈이라는 말은 다른 누군가에 의해서 미리 만들어진 하나의 작은 프로그램이라는 뜻. 물론 내가 직접 모듈을 만들 수도 있다. 여기서는 가장 먼저 tkinter 모듈을 불러들이고 tkinter라는 긴 이름 대신에 tk라는 짧은 별명을 사용하기로 한다.

 

 

■ PIL 모듈에 대해 두 가지 불러오기 방식의 차이

 

from PIL import ImageImageTk

PIL은 pillow 모듈을 뜻한다. 

 

PIL 모듈 내부에는 더 작은 다수의 하위 모듈들이 포함되어 있다. 그 중에서 두 개의 하위 모듈인 Image 모듈과 ImageTk 모듈을 불러들인다. 모듈들 사이에도 계급이 존재하는 셈이다. 초등학교 반장이나 컴반 조교급 모듈, 혹은 마을 이장이나 동장 모듈이 있는가 하면, 훨씬 높은(?) 도지사나 국회의원급, 한 나라를 대표하는 국방부 장관이나 국무총리급 모듈도 있다고 보면 된다. ^.^; 여기서는 PIL이 소속 하위 모듈들의 대표이다. 하위 모듈들은 불러오기 방식에 따라 표기법이 달라지는 것에 주의가 필요하다. import 단어가 맨 앞에 오는 경우가 있고 중간에 오는 경우가 있다. import와 같이 파이썬 그 자신이 혼자서만 사용하려고 미리 예약, 예매, 선점한 단어들을 전문 용어(?)로 '키워드'라고 한다. 이런 키워드들은 변수 이름으로 사용할 수 없다. 다른 용도로 사용할 수 없다.

 

1) import PIL

2) from PIL import Image, ImageTk

 

1) 방식으로 불러오기를 하면, PIL.Image.function()

2) 방식으로 불러오기를 하면, Image.function()처럼 사용할 수 있다.

 

불러오기(import) 방식에 따라서 모듈 대표 이름을 추가하거나 빼야 한다.

turtle, tkinter 모듈들도 마찬가지이다. 대부분의 모듈들은 이 방법을 따른다.

 

 

■ 외부 모듈인 PIL 모듈 설치 과정이 필요할 수도 있다.

 

PIL 모듈은 파이썬에 내장되어 있지 않다. 이런 모듈을 '부 모듈'이라고 한다. 내가 만든 파이썬 소스 코드에 PIL 모듈을 사용하려면, 먼저 PIL 모듈을 내 컴퓨터에 설치해야 한다. 이 과정에는 '관리자권한'이 필요할 수도 있다. 어쨌거나 설치하려면 CMD 창이나 파워쉘 창에서 다음 명령을 실행하면 설치할 수 있다. (여기에, 인터넷 연결이 필요함!!) 

 

pip install pillow

 

 

2) 단계 : tkinter root 윈도우를 만들고

■  Tkinter 윈도우의 생성 과정 : 이런 저런 옵션들을 추가해서 일단 가장 기본이 되는 tkinter 윈도우부터 만들자.

 

tkWindow1 = tk.Tk()
tkWindow1.config(bg="gray", highlightcolor="lightblue", highlightthickness=15, relief="solid")
tkWindow1.geometry("1024x800+200+200")
tkWindow1.title("Canvas에 이미지 표시하기")

 

 

참고 1. Tkinter root 윈도우 배경색 설정

- root 윈도우 테두리 배경색 지정은 안 되지만, 위 코드처럼 하면 간접적인 테두리 효과를 나타낼 수 있다. 

- relief 옵션 추가, 하이라이트 두께와 색상을 지정할 것.

- 프레임에는 테두리 가능함. 옵션들의 초간단 의미.

- "flat": 기본값(테두리 없음) "solid": 단색 테두리 "raised": 양각 테두리 "sunken": 음각 테두리,

- "ridge": 돌출 테두리 "groove": 홈 테두리

- config() 메서드 다른 옵션들 : highlightbackground="lightgray" , highlightcolor="lightgray"

 

tkWindow1.config(bg="gray", highlightcolor="lightblue", highlightthickness=15, relief="solid")

 

- 실제로는 색상과 두께를 좀 더 세밀하게 조정해서 사용해야 함.

- 컬러는 Tkinter 내장 컬러명 및 웹컬러 표기법 지원 : #RRGGBB, #6699FF 처럼. 가능.

- 컬러 표시 예 : lightyellow, lightblue, #ADD8E6

 

 

■ 참고 2. Tkinter root 윈도우의 배경색을 지정하는 다른 방법.
- Frame을 생성하고 배경색을 지정해준다. 
frame = tk.Frame(root, bg="lightyellow")
frame.pack(fill="both", expand=True)  # 윈도우 전체를 채우도록 배치
이후의 위젯들은 이 frame에 배치해야 한다.



3) 단계 : tkinter.canvas를 만들고

# Canvas 위젯 생성 (배경색: lightblue)
canvas = tk.Canvas(tkWindow1, width=860, height=640, bg="lightblue")
# canvas의 외부 여백 추가
canvas.pack(padx=40, pady=40)
"""
# canvas의 외부 여백 추가 다른 방법 :
# place() 메서드 방법.
# canvas.place(x=20, y=20)    #
"""

 

4) 단계 : 외부 이미지 파일 정보를 불러오고

# 외부 이미지 파일 로드
image_path = "data/pic000_.png" 

# 표시하려는 이미지 파일 경로, like Processing v4.3.4. data 폴더에 이미지 저장.

# 메인 소스코드 파일인 ~~.py의 위치를 기준으로 그 하위 폴더로 data  폴더를 만들고

# 그곳에 pic000_.png 파일 저장.

 

 

5) 단계 : 이 정보를 이용해서 이미지 파일을 실제로 열고, 크기를 재조정한 다음

image = Image.open(image_path)  # 이미지 열기
image = image.resize((400, 400))  # Canvas 크기에 맞게 이미지 크기 조정 (선택 사항)

# 위 두 줄은 단일 명령 체인으로 합치기 가능, 코드 가독성 때문에 풀어서 진행함.

# image = Image.open(image_path).resize((400, 400))

 

Image.open() 한다고 해서 실제로 이미지가 화면에 나타나지는 않는다. 메모장에서 텍스트 파일을 open()하면 그 텍스트 파일은 즉시 화면에 나타나지만 Image.open()에서의 open은 윈도우 운영체제의 파일 핸들을 차지한다는 뜻이 된다. 이 파일은 운영체제 차원에서 '열린 상태'의 파일이기 때문에 다른 프로그램들은 파일 내용 수정을 위해서 이 파일에 손 댈 수 없다. 파이썬 프로그램이 파일 통제 권한을 독차지하는 상태가 된다. 파일이 열린 상태에서는 다른 프로그램, 예를 들어 그림 파일 보기 프로그램으로 유명한 XN-View나 Pickpic 같은 그림 관련 프로그램에서 열 수는 있어도 이 파일을 수정할 수는 없는 상태가 된다. 일종의 보호 락이 걸린 상태가 된다.  다른 프로그램에서 이 파일을 수정하려면 먼저 열린 상태의 파일을 닫아야 한다.

 

 

6) 단계 : 재조정된 파일을 ImageTk 모듈의 전용 포토이미지로 변환한다. 오리지널 tkinter의 포토이미지 확장판임.

tk_image = ImageTk.PhotoImage(image)

 

ImageTk는 Python의 Pillow (PIL) 라이브러리가 제공하는 모듈 중 하나로, Tkinter에서 이미지를 표시할 수 있도록 PhotoImage 객체를 확장한 것입니다. Tkinter는 Python의 GUI 라이브러리로, ImageTk를 통해 Pillow에서 지원하는 다양한 이미지 형식을 Tkinter 위젯에서 사용할 수 있게 만들어줍니다.

 

 

PhotoImage 객체도 Tkinter 소속임.

PhotoImage 객체는 Tkinter 소속입니다. Tkinter는 Python의 기본 GUI 라이브러리이며, PhotoImage는 Tkinter에서 제공하는 이미지 객체로, GIF나 PGM/PPM 형식의 이미지를 지원합니다. 하지만 여기서 중요한 점은 Tkinter의 PhotoImage는 기본적으로 제한된 이미지 포맷만 지원한다는 것입니다. 그래서 더 다양한 포맷(예: JPEG, PNG)을 다루기 위해 Pillow 라이브러리의ImageTk.PhotoImage를 많이 사용합니다. 그래서 요약하자면:


Tkinter의 PhotoImage : Tkinter 자체 제공.
Pillow의 ImageTk.PhotoImage : Tkinter와 Pillow를 통합해서 더 많은 이미지 포맷을 지원.

 

 

7) 단계 : 이 tkinter 포토이미지를 이용해서 캔버스에 실제로 이미지를 나타낸다(create).

# Canvas에 실제로 이미지 표시
canvas.create_image(40, 40, anchor=tk.NW, image=tk_image)

 

8) 단계 : tkinter root 윈도우 메인 루프 작동시키기.

# Tkinter 메인 루프 실행
tkWindow1.mainloop()

# 프로그램이 종료되면 열린 포토이미지 파일은 자동으로 닫힌다.

 

# EOF(=END of File).

 

 

■ 응용 연습 과제

1) 이미지 여러개 표시하기

2) 이미지들 표시 위치 변경하기

 

 

기타 사항 : 외부 모듈 pillow 설치시 에러가 발생하는 경우

 

1) 정상적인 경우 (PowerShell이나 CMD 창에서 실행) :

Windows 11 터미널 (관리자)
Windows PowerShell
Copyright (C) Microsoft Corporation. All rights reserved.
새로운 기능 및 개선 사항에 대 한 최신 PowerShell을 설치 하세요! https://aka.ms/PSWindows
PS C:\Users\User> pip install pillow
Requirement already satisfied: pillow in c:\python_3_12_2_\lib\site-packages (11.0.0)
PS C:\Users\User>
 # CMD의 경우도 비슷합니다.

 

 

2) 비정상적인 경우 (PowerShell이나 CMD 창에서 실행) :

3) 이전 버전의 pip 관련 메시지가 나타나는 경우, pip 자체를 업데이트하라는 말. 

 

( tbc... )

 

...

...

 

 

5. Files

 

Here you are! ^.^;

pic000_.png
0.00MB
Tkinter_Canvas_Ex_000_.py
0.00MB
Tkinter_Canvas_Ex_000_.zip
0.01MB

 

 

20초 영어 회화 : 대화 상대가 파일을 요청했고, 그 파일을 건네면서 "여기 있습니다"라고 말할 경우, 영어로는 간단히 이렇게 표현할 수 있습니다:
"Here you go." (일상적이고 친근한 표현)
"Here it is." (조금 더 단순하고 직설적인 표현)
"Here you are." (정중하면서도 자연스러운 표현)

 

 

6. Ref.

1) 김영탁, [ 컴퓨팅 사고와 파이썬 프로그래밍 ] 2022. 홍릉.

2) 강환수, 신용현 공저, [ 파이썬으로 배우는 누구나 코딩 ] 2019. 홍릉.

3) Mark Lutz, [ Programming Python, 4th Ed. ] 2011. O'Reilly.

 

 

Happy Programming!

^.^;