Python/Sprite Anim2019. 2. 1. 15:04

Python에서 Pillow 모듈을 사용한 스프라이트 애니메이션 예제


Pillow 모듈 설치

PIL(Python Image Library) 프로젝트가 중단되고 그 후속 프로젝트가 Pillow 이며 Python 3 이 타겟이다


Pillow 매뉴얼

pillow.pdf


원문강좌 참조: http://zetcode.com/python/pillow/


Pillow 모듈 설치

Python이 설치되어 있고 PATH 환경변수에 Python의 경로가 설정되어 있다면 윈도우의 CMD 콘솔에서 다음과 같은 명령을 통해 Pillow 모듈을 간단하게 설치할 수 있다


pip install pillow



PIL 이미지를 tk 이미지로 변환하여 tk Canvas에 그리는 예

from tkinter import *
from PIL import Image, ImageTk

master = Tk()
master.title("Canvas에 PIL 이미지 그리기")
master.geometry("600x400+300+100")
master.resizable(False, False)

canvas = Canvas(master, width=600, height=400, bg="orange")
canvas.pack()
pil_img = Image.open("D:/test/explosion17.png")

# 이미지를 다루는 외부 프로그램을 열고 이미지를 보여준다
#pil_img.show()

# PIL 이미지를 tkinter 이미지와 호환되도록 변환
tk_img = ImageTk.PhotoImage(pil_img)

# tkinter Canvas에 이미지를 그린다
image = canvas.create_image(0, 0, anchor=NW, image=tk_img)

master.mainloop()



소스 이미지에서 특정 영역의 이미지 데이터만 가져오기

스프라이트 시트에서 애니메이션의 한 프레임에 해당하는 이미지 영역을 선택적으로 읽어온다

from tkinter import *
from PIL import Image, ImageTk

master = Tk()
master.title("Canvas에 PIL 이미지 그리기")
master.geometry("600x400+300+100")
master.resizable(False, False)

canvas = Canvas(master, width=600, height=400, bg="orange")
canvas.pack()
pil_img = Image.open("D:/test/explosion17.png")

# 스프라이트 시트에서 한 프레임 이미지를 읽어온다
box = 0,0,64,64
pil_frame_img = pil_img.crop(box)

# PIL 이미지를 tkinter 이미지와 호환되도록 변환
frame_img = ImageTk.PhotoImage(pil_frame_img)

# tkinter Canvas에 이미지를 그린다
image = canvas.create_image(0, 0, anchor=NW, image=frame_img)

master.mainloop()



스프라이트 애니메이션을 구현한 예

사용된 스프라이트 시트는 이 페이지 하단에 첨부


from tkinter import *
from PIL import Image, ImageTk
import time

master = Tk()
master.title("스프라이트 애니메이션 예제")
master.geometry("600x400+300+100")
master.resizable(False, False)

canvas = Canvas(master, width=600, height=400, bg="orange")
canvas.pack()

# 애니메이션을 구성하는 모든 프레임 이미지가 저장된 스프라이트 시트를 로드한다
pil_img = Image.open("D:/test/explosion17.png")

# 스프라이트 시트에서 확인된 한 프레임 영역의 폭(w)과 높이(h)
w = 64
h = 64

# 스프라이트 시트로부터 순차적으로 프레임 이미지를 읽어와서 캔바스에 표시한다
for y in range(5) :
for x in range(5) :

# 스프라이트 시트에서 읽어올 한 프레임 영역의 좌표를 계산한다
box = x*w, y*w, (x+1)*h, (y+1)*h
# 스프라이트 시트에서 한 프레임 영역 이미지를 읽어온다
pil_frame_img = pil_img.crop(box)
# PIL 이미지를 tkinter 이미지로 변환한다
frame_img = ImageTk.PhotoImage(pil_frame_img)
# tkinter 이미지를 캔바스에 그린다
image = canvas.create_image(0, 0, anchor=NW, image=frame_img)
# 윈도우(화면)를 업데이트한다
master.update()
# 루프를 0.025초 쉰다(애니메이션 속도를 결정함)
time.sleep(.025)

master.mainloop()



Posted by cwisky
Python/Math2019. 1. 31. 22:14

파이썬 math 모듈에 포함된 함수


import math

# math 모듈이 필요 없는 수학 함수
print(" 2**3 : "+ str( 2**3 )) # 8
print(" abs(-25) : " + str ( abs(-25) ) ) # 25
print(" round(1.5) : " + str( round(1.5))) # 2
print(" round(1.1234567, 1) : " + str( round(1.1234567, 1))) # 1.1
print(" sum([1,2,3,4]) : "+ str( sum([1,2,3,4]))) # 10
print(" max([1,2,3,4]) : "+ str( max([1,2,3,4]))) # 4
print(" min([1,2,3,4]) : "+ str( min([1,2,3,4]))) # 1
print(" pow(2,3) : "+ str(pow(2,3)) ) # 8
print(" divmod(5,2) "+ str( divmod(5,2))) # (2,1)

# 여기서부터는 math 모듈이 필요함

print("pi:"+ str ( math.pi ) ) # 3.141592653589793
print("e:"+ str ( math.e ) ) # 2.718281828459045

print(" math.ceil(3.14) : "+ str( math.ceil(3.14))) # 4
print(" math.floor(3.14) : "+ str( math.floor(3.14))) # 3
print(" math.trunc(2.3) : "+ str( math.trunc(2.3))) # 2
print(" math.factorial(4) : "+ str( math.factorial(4))) # 24
print(" math.pow(2,3) "+ str( math.pow(2,3))) # 8
print(" math.sqrt(9) "+ str( math.sqrt(9))) # 3
print(" math.copysign(1.5, -1.3) : "+ str(math.copysign(1.5, -1.3))) # -1.5
print(" math.fabs(-2.7) : "+ str(math.fabs(-2.7))) # 2.7
print(" math.fmod(-13.2, 3) : "+ str(math.fmod(-13.2,3))) # -1.1999999999999993
print(" math.fsum([1,2,3]) : "+ str( math.fsum([1,2,3]))) # 6.0
print(" math.modf(2.718) : "+ str( math.modf(2.7))) # (0.7000000000000002, 2.0)
print(" math.exp(2) : "+ str( math.exp(2))) # 7.38905609893065

# 삼각함수
print(" math.degrees(math.pi) : "+ str( math.degrees(math.pi))) # 180.0
print(" math.radians(180) : "+ str( math.radians(180))) # pi

rad = math.pi/2 # 90 deg
sinv = math.sin(rad)
cosv = math.cos(rad)
tanv = math.tan(rad)

# 역삼각함수
math.asin(sinv)
math.acos(cosv)
math.atan(tanv)
math.atan2(sinv, cosv)

# 쌍곡선 함수
sinhv = math.sinh(rad)
coshv = math.cosh(rad)
tanhv = math.tanh(rad)

# 역쌍곡선 함수
math.asinh(sinhv)
math.acosh(coshv)
math.atanh(tanhv)

# 밑을 지정하는 일반로그
print(" math.log(8,2) "+ str( math.log(8,2))) # 3.0

# 밑이 자연상수(e)인 자연로그
val = math.pow( math.e, 3 )
print(" math.log("+str(val)+") "+ str( math.log(val))) # 3.0

# 밑이 10인 상용로그
print(" math.log10(100) "+ str( math.log10(100))) # 2.0

# 복소수
comp1 = 2 + 3j
comp2 = 3 + 4j
comp3 = comp1 + comp2
print(comp3) # 5 + 7j


Posted by cwisky
Python/Ball Anim2019. 1. 31. 18:47

tkinter 모듈을 이용하여 사각영역에서 공이 이동하면서 테두리에서 반사하는 기본적인 애니메이션 만들기


from tkinter import *
import time

win = Tk()
win.geometry("800x800")
win.title("이동 애니메이션 기본")

c = Canvas(win ,width=800 ,height=800)
c.pack()

oval = c.create_oval(5,5,60,60,fill='red')

a = 1
b = 1

for x in range(0 ,100):
c.move(oval,a,b)
win.update()
time.sleep(.03)

win.mainloop()



경계에 충돌하고 반사하는 공 애니메이션

from tkinter import *
import time

win = Tk()
win.title("First title")
win.geometry("600x400")

c = Canvas(win ,width=600 ,height=400, bg="#559955")
c.pack()

oval = c.create_oval(5,5,60,60,fill='white')

xd = 2
yd = 2

while True:
c.move(oval,xd,yd)
# 현재 볼의 위치([x1,y1, x2,y2])를 구함
p = c.coords(oval) # Return a list of coordinates for the item given in ARGS.

if p[3] >= 400 or p[1] <=0: # 상하 영역을 벗어났는지 확인
yd = -yd
if p[2] >=600 or p[0] <=0: # 좌우 영역을 벗어났는지 확인
xd = -xd

win.update()
time.sleep(0.01)

win.mainloop()


Posted by cwisky