from tkinter import *
from tkinter.filedialog import *
from tkinter.simpledialog import *
#이미지 처리 기능 제공, Pillow 라이브러리
from PIL import Image, ImageFilter, ImageEnhance, ImageOps
#전역변수 선언
window, canvas, paper = None, None, None
photo_1, photo_2 = None, None
orix, oriy = 0, 0
window, canvas, paper = None, None, None
photo_1, photo_2 = None, None
orix, oriy = 0, 0
def displayImage(img, width, height):
global window, canvas, paper, photo_1, photo_2, orix, oriy
#화면 크기를 width, height에 맞춰 설정
window.geometry(str(width)+"x"+str(height))
print(str(width), str(height))
if canvas != None: #기존에 canvas에 출력한 그림이 존재 시
canvas.destroy() #canvas 를 지움
canvas = Canvas(window, width= width, height = height) #캔버스 생성
paper = PhotoImage(width=width, height=height)
global window, canvas, paper, photo_1, photo_2, orix, oriy
#화면 크기를 width, height에 맞춰 설정
window.geometry(str(width)+"x"+str(height))
print(str(width), str(height))
if canvas != None: #기존에 canvas에 출력한 그림이 존재 시
canvas.destroy() #canvas 를 지움
canvas = Canvas(window, width= width, height = height) #캔버스 생성
paper = PhotoImage(width=width, height=height)
#이미지의 사이즈 절반의 값의 위치에 이미지 생성(paper에 그리기 위해서)
canvas.create_image((width/2, height/2),image=paper)
rgbString=""
rgbImage=img.convert('RGB')
canvas.create_image((width/2, height/2),image=paper)
rgbString=""
rgbImage=img.convert('RGB')
#cnt =0
#높이와 너비 만큼 루프를 토애 rgb 값을 getpixel()로 추출, 16진수 형태로 rgbString에 누적.
for i in range(0, height):
tmpString = ""
for j in range(0,width):
#복사된 이미지 객체에 대해 getpixel() 이용해 r,g,b 값을 가져올 수 있음.
r, g, b = rgbImage.getpixel((j,i))
tmpString += "#%02x%02x%02x " %(r,g,b) #x 뒤에는 한칸 공백 남겨두어야 가로에 대한 색상 수치를 연속적으로 저장 가능
#cnt += 1
rgbString += "{" + tmpString + "} " #뒤에 한칸의 공백을 남겨두어야 함
#print(rgbString)
#print(cnt)
#rgbString 값을 paper에 대입, put()
paper.put(rgbString)
canvas.pack()
#높이와 너비 만큼 루프를 토애 rgb 값을 getpixel()로 추출, 16진수 형태로 rgbString에 누적.
for i in range(0, height):
tmpString = ""
for j in range(0,width):
#복사된 이미지 객체에 대해 getpixel() 이용해 r,g,b 값을 가져올 수 있음.
r, g, b = rgbImage.getpixel((j,i))
tmpString += "#%02x%02x%02x " %(r,g,b) #x 뒤에는 한칸 공백 남겨두어야 가로에 대한 색상 수치를 연속적으로 저장 가능
#cnt += 1
rgbString += "{" + tmpString + "} " #뒤에 한칸의 공백을 남겨두어야 함
#print(rgbString)
#print(cnt)
#rgbString 값을 paper에 대입, put()
paper.put(rgbString)
canvas.pack()
def func_open():
#photo는 원본 이미지 저장 변수, photo2는 이미지 처리후 나타나는 결과 이미지 저장
#orix, oriy : 원본 이미지 폭, 높이 저장 변수
global window, canvas, paper, photo_1,photo_2, orix, oriy
#파일 다이얼로그 : 원하는 이미지 사용자가 선택할 수 있도록
readFp = askopenfilename(parent=window, filetypes=(("모든 그림 파일","*.jpg;*.jpeg;*.bmp;*.png;*.tif;*.gif"),("모든파일","*.*")))
#파이썬 제공 photoImage() 가 아닌 Pillow 라이브러리의 Image.open() 함수 사용, photoImage() 클래스 : 이미지 파일 확장자를 .gif, .png 만 지원
photo_1 = Image.open(readFp).convert('RGB') #사용자 이미지 RGB모드로 변환
orix = photo_1.width
oriy = photo_1.height
#원본이미지(photo_1) 를 photo_2 로 복사
photo_2 = photo_1.copy()
newX = photo_2.width
newY = photo_2.height
print(newX,newY) #복사된 이미지의 width, height
#복사한 내용으로 displayImage() 함수 호출
displayImage(photo_2, newX, newY)
#photo는 원본 이미지 저장 변수, photo2는 이미지 처리후 나타나는 결과 이미지 저장
#orix, oriy : 원본 이미지 폭, 높이 저장 변수
global window, canvas, paper, photo_1,photo_2, orix, oriy
#파일 다이얼로그 : 원하는 이미지 사용자가 선택할 수 있도록
readFp = askopenfilename(parent=window, filetypes=(("모든 그림 파일","*.jpg;*.jpeg;*.bmp;*.png;*.tif;*.gif"),("모든파일","*.*")))
#파이썬 제공 photoImage() 가 아닌 Pillow 라이브러리의 Image.open() 함수 사용, photoImage() 클래스 : 이미지 파일 확장자를 .gif, .png 만 지원
photo_1 = Image.open(readFp).convert('RGB') #사용자 이미지 RGB모드로 변환
orix = photo_1.width
oriy = photo_1.height
#원본이미지(photo_1) 를 photo_2 로 복사
photo_2 = photo_1.copy()
newX = photo_2.width
newY = photo_2.height
print(newX,newY) #복사된 이미지의 width, height
#복사한 내용으로 displayImage() 함수 호출
displayImage(photo_2, newX, newY)
def func_save():
global window, canvas, paper, photo_1, photo_2, orix, oriy
if photo_2 == None: #복사된 객체가 None 이므로 없음을 의미
return #함수 종료
saveFp = asksaveasfile(parent=window, mode="w", defaultextension=".jpg",filetypes=(("JPG","*.jpg;*.jpeg"),("모든파일","*.*"))) #저장할때 jpg, jpeg 로 저장하도록
photo_2.save(saveFp.name) #사용자 입력 파일명으로 저장
def func_exit():
exit() #종료
global window, canvas, paper, photo_1, photo_2, orix, oriy
if photo_2 == None: #복사된 객체가 None 이므로 없음을 의미
return #함수 종료
saveFp = asksaveasfile(parent=window, mode="w", defaultextension=".jpg",filetypes=(("JPG","*.jpg;*.jpeg"),("모든파일","*.*"))) #저장할때 jpg, jpeg 로 저장하도록
photo_2.save(saveFp.name) #사용자 입력 파일명으로 저장
def func_exit():
exit() #종료
def func_zoomin():
global window, canvas, paper, photo_1, photo_2, orix, oriy
scale = askinteger("확대배수","확대할 배수 입력",minvalue="2",maxvalue="5")
photo_2 = photo_1.copy()
#pillow 의 resize() : 간단히 이미지 확대/축소 가능, 배수-> 메모리 사용량 증가함->시간 증가
photo_2 = photo_2.resize((int(orix * scale),int(oriy * scale)))
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2,newX,newY)
global window, canvas, paper, photo_1, photo_2, orix, oriy
scale = askinteger("확대배수","확대할 배수 입력",minvalue="2",maxvalue="5")
photo_2 = photo_1.copy()
#pillow 의 resize() : 간단히 이미지 확대/축소 가능, 배수-> 메모리 사용량 증가함->시간 증가
photo_2 = photo_2.resize((int(orix * scale),int(oriy * scale)))
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2,newX,newY)
def func_zoomout():
global window, canvas, paper, photo_1, photo_2, orix, oriy
scale = askinteger("축소배수", "축소할 배수 입력", minvalue="2", maxvalue="5")
photo_2 = photo_1.copy()
# pillow 의 resize() : 간단히 이미지 확대/축소 가능, 배수-> 메모리 사용량 증가함->시간 증가
photo_2 = photo_2.resize((int(orix / scale), int(oriy / scale)))
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
global window, canvas, paper, photo_1, photo_2, orix, oriy
scale = askinteger("축소배수", "축소할 배수 입력", minvalue="2", maxvalue="5")
photo_2 = photo_1.copy()
# pillow 의 resize() : 간단히 이미지 확대/축소 가능, 배수-> 메모리 사용량 증가함->시간 증가
photo_2 = photo_2.resize((int(orix / scale), int(oriy / scale)))
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
def func_mirror_1():
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
#이미지 상하 반전, transpose(Image,FLIP_TOP_BOTTOM)
photo_2 = photo_2.transpose(Image.FLIP_TOP_BOTTOM)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2,newX,newY)
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
#이미지 상하 반전, transpose(Image,FLIP_TOP_BOTTOM)
photo_2 = photo_2.transpose(Image.FLIP_TOP_BOTTOM)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2,newX,newY)
def func_mirror_2():
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
# 이미지 좌우 반전, transpose(Image,FLIP_LEFT_RIGHT)
photo_2 = photo_2.transpose(Image.FLIP_LEFT_RIGHT)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
# 이미지 좌우 반전, transpose(Image,FLIP_LEFT_RIGHT)
photo_2 = photo_2.transpose(Image.FLIP_LEFT_RIGHT)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
def func_rotate():
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
degree = askinteger("회전기능","회전각도입력",minvalue=0,maxvalue=360)
#이미지 회전 : rotate(), 매개변수 expand : True : 회전결과 이미지를 확대, False는 원본크기 유지
photo_2 = photo_2.rotate(degree, expand=True)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2,newX,newY)
def func_bright():
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
value = askfloat("밝게","값입력(1.0-16.0)",minvalue=1.0,maxvalue=16.0)
#이미지 밝게, 어둡게 설정, ImageEnhance.Brightness(이미지.enhance(밝기값) 함수 사용
#1.0 : 원본, 1.0 초과 : 이미지 밝게 처리, 1.0 미만 : 이미지 어둡게 처리
photo_2 = ImageEnhance.Brightness(photo_2).enhance(value)
newX = photo_2.width
newY= photo_2.height
displayImage(photo_2,newX,newY)
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
degree = askinteger("회전기능","회전각도입력",minvalue=0,maxvalue=360)
#이미지 회전 : rotate(), 매개변수 expand : True : 회전결과 이미지를 확대, False는 원본크기 유지
photo_2 = photo_2.rotate(degree, expand=True)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2,newX,newY)
def func_bright():
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
value = askfloat("밝게","값입력(1.0-16.0)",minvalue=1.0,maxvalue=16.0)
#이미지 밝게, 어둡게 설정, ImageEnhance.Brightness(이미지.enhance(밝기값) 함수 사용
#1.0 : 원본, 1.0 초과 : 이미지 밝게 처리, 1.0 미만 : 이미지 어둡게 처리
photo_2 = ImageEnhance.Brightness(photo_2).enhance(value)
newX = photo_2.width
newY= photo_2.height
displayImage(photo_2,newX,newY)
def func_dark():
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
value = askfloat("밝게", "값입력(1.0-16.0)", minvalue=0.0, maxvalue=1.0)
# 이미지 밝게, 어둡게 설정, ImageEnhance.Brightness(이미지.enhance(밝기값) 함수 사용
# 1.0 : 원본, 1.0 초과 : 이미지 밝게 처리, 1.0 미만 : 이미지 어둡게 처리
photo_2 = ImageEnhance.Brightness(photo_2).enhance(value)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
value = askfloat("밝게", "값입력(1.0-16.0)", minvalue=0.0, maxvalue=1.0)
# 이미지 밝게, 어둡게 설정, ImageEnhance.Brightness(이미지.enhance(밝기값) 함수 사용
# 1.0 : 원본, 1.0 초과 : 이미지 밝게 처리, 1.0 미만 : 이미지 어둡게 처리
photo_2 = ImageEnhance.Brightness(photo_2).enhance(value)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
def func_blur():
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
#이미지에 특수효과 주기, filter(ImageFileter.필터),BLUR,DETAIL,CONTOUR,EDGE_ENHANCE, EDGE_ENHANCE_MORE, FIND_EDGES, SHARPEN, SMOOTH...
photo_2 = photo_2.filter(ImageFilter.BLUR)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
#이미지에 특수효과 주기, filter(ImageFileter.필터),BLUR,DETAIL,CONTOUR,EDGE_ENHANCE, EDGE_ENHANCE_MORE, FIND_EDGES, SHARPEN, SMOOTH...
photo_2 = photo_2.filter(ImageFilter.BLUR)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
def func_embo():
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
#이미지에 특수효과 주기, filter(ImageFileter.필터),BLUR,DETAIL,CONTOUR,EDGE_ENHANCE, EDGE_ENHANCE_MORE, FIND_EDGES, SHARPEN, SMOOTH...
photo_2 = photo_2.filter(ImageFilter.EMBOSS)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
#이미지에 특수효과 주기, filter(ImageFileter.필터),BLUR,DETAIL,CONTOUR,EDGE_ENHANCE, EDGE_ENHANCE_MORE, FIND_EDGES, SHARPEN, SMOOTH...
photo_2 = photo_2.filter(ImageFilter.EMBOSS)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
def func_bw():
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
#컬러 이미지를 흑백이미지로 변경, ImageOps.grayscale(이미지) 사용해야 함.
photo_2 = ImageOps.grayscale(photo_2)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
global window, canvas, paper, photo_1, photo_2, orix, oriy
photo_2 = photo_1.copy()
#컬러 이미지를 흑백이미지로 변경, ImageOps.grayscale(이미지) 사용해야 함.
photo_2 = ImageOps.grayscale(photo_2)
newX = photo_2.width
newY = photo_2.height
displayImage(photo_2, newX, newY)
if __name__ =="__main__":
#gui
window = Tk() #윈도우 생성
window.geometry("250x250") #윈도우 크기 설정
window.title("PhotoEdit")
mainmenu = Menu(window)
window.config(menu = mainmenu)
filemenu = Menu(mainmenu, tearoff=False) #tearoff : 메뉴의 점선 false
window = Tk() #윈도우 생성
window.geometry("250x250") #윈도우 크기 설정
window.title("PhotoEdit")
mainmenu = Menu(window)
window.config(menu = mainmenu)
filemenu = Menu(mainmenu, tearoff=False) #tearoff : 메뉴의 점선 false
#add_cascade : 상위메뉴와 하위메뉴 연결(mainmenu-filemenu), 다른 메뉴가 확장되도록 설정
mainmenu.add_cascade(label="파일",menu=filemenu)
mainmenu.add_cascade(label="파일",menu=filemenu)
#add_command : menu 항목 생성
filemenu.add_command(label="파일열기",command=func_open)
filemenu.add_command(label="파일저장",command=func_save)
#구분선
filemenu.add_separator()
filemenu.add_command(label="종료",command=func_exit)
image1Menu = Menu(mainmenu, tearoff=False)
filemenu.add_separator()
filemenu.add_command(label="종료",command=func_exit)
image1Menu = Menu(mainmenu, tearoff=False)
mainmenu.add_cascade(label="이미지처리_1",menu=image1Menu)
image1Menu.add_command(label="확대",command=func_zoomin)
image1Menu.add_command(label="확대", command=func_zoomout)
image1Menu.add_separator()
image1Menu.add_command(label="상하반전",command=func_mirror_1)
image1Menu.add_command(label="좌우반전", command=func_mirror_2)
image1Menu.add_command(label="회전", command=func_rotate)
image2Menu = Menu(mainmenu, tearoff=False)
image1Menu.add_command(label="확대",command=func_zoomin)
image1Menu.add_command(label="확대", command=func_zoomout)
image1Menu.add_separator()
image1Menu.add_command(label="상하반전",command=func_mirror_1)
image1Menu.add_command(label="좌우반전", command=func_mirror_2)
image1Menu.add_command(label="회전", command=func_rotate)
image2Menu = Menu(mainmenu, tearoff=False)
mainmenu.add_cascade(label="이미지처리_2",menu=image2Menu)
image2Menu.add_command(label="밝게",command=func_bright)
image2Menu.add_command(label="어둡게", command=func_dark)
image2Menu.add_separator()
image2Menu.add_command(label="블러",command=func_blur)
image2Menu.add_command(label="엠보싱", command=func_embo)
image2Menu.add_command(label="흑백", command=func_bw)
window.mainloop()
image2Menu.add_command(label="밝게",command=func_bright)
image2Menu.add_command(label="어둡게", command=func_dark)
image2Menu.add_separator()
image2Menu.add_command(label="블러",command=func_blur)
image2Menu.add_command(label="엠보싱", command=func_embo)
image2Menu.add_command(label="흑백", command=func_bw)
window.mainloop()
댓글
댓글 쓰기