코드
from tkinter import *
from tkinter.messagebox import *
from tkinter.filedialog import *
from tkinter.simpledialog import *
from tkinter.colorchooser import *
from tkinter import filedialog
from wand.image import *
window, canvas, paper = None, None, None
photo, photo2 = None, None
oriX, oriY, newX, newY = 0, 0, 0, 0
x1, y1, x2, y2 = None, None, None, None
openNum, newNum = 0, 0
penColor = 'black'
penWidth = 3
def displayImage(img, width, height) :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
if canvas != None :
canvas.destroy()
canvas = Canvas(window, width=width, height=height, highlightthickness=0)
paper = PhotoImage(width=width, height=height)
canvas.create_image((width/2, height/2), image=paper, state="normal")
blob = img.make_blob(format='png')
paper.put(blob)
canvas.place(x=(1050-width)/2, y=(940-height)/2)
def mouseClick(event) :
global x1, y1, x2, y2, penColor, penWidth
x1, y1 = (event.x), (event.y)
def mouseDrop(event) :
global x1, y1, x2, y2, penColor, penWidth
x2, y2 = (event.x), (event.y)
canvas.create_line(x1, y1, x2, y2, width=penWidth, fill=penColor)
def circleClick(event) :
global x1, y1, x2, y2, penColor, penWidth
x1, y1 = (event.x-1), (event.y-1)
def circleDrop(event) :
global x1, y1, x2, y2, penColor, penWidth
x2, y2 = (event.x+1), (event.y+1)
canvas.create_oval(x1, y1, x2, y2, width=penWidth, fill=None, outline=penColor)
def recDrop(event) :
global x1, y1, x2, y2, penColor, penWidth
x2, y2 = (event.x+1), (event.y+1)
canvas.create_rectangle(x1, y1, x2, y2, width=penWidth, fill=None, outline=penColor)
def paint(event) :
global x1, y1, x2, y2, penColor, penWidth
x1, y1 = (event.x-1), (event.y-1)
x2, y2 = (event.x+1), (event.y+1)
canvas.create_oval(x1, y1, x2, y2, width=penWidth, fill=penColor, outline=penColor)
def getColor() :
global x1, y1, x2, y2, penColor, penWidth
color = askcolor()
penColor = color[1]
def getWidth() :
global x1, y1, x2, y2, penColor, penWidth
penWidth = askinteger("펜 두께", "펜 두께(1~10)를 입력하세요.", minvalue=1, maxvalue=10)
def func_pen() :
global x1, y1, x2, y2, penColor, penWidth
canvas.bind("<B1-Motion>", paint)
def func_line() :
global x1, y1, x2, y2, penColor, penWidth
canvas.bind("<Button-1>", mouseClick)
canvas.bind("<ButtonRelease-1>", mouseDrop)
def func_circle() :
global x1, y1, x2, y2, penColor, penWidth
canvas.bind("<Button-1>", circleClick)
canvas.bind("<ButtonRelease-1>", circleDrop)
def func_rectangle() :
global x1, y1, x2, y2, penColor, penWidth
canvas.bind("<Button-1>", circleClick)
canvas.bind("<ButtonRelease-1>", recDrop)
def func_new() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY, openNum, newNum, fileName, frameDraw, penColor, penWidth
ask_save()
if canvas != None :
canvas.destroy()
width = askinteger("가로 사이즈", "캔버스의 <가로> 사이즈(1~800)", minvalue=1, maxvalue=800)
height = askinteger("세로 사이즈", "캔버스의 <세로> 사이즈(1~750)", minvalue=1, maxvalue=750)
canvas = Canvas(window, width=width, height=height, bg="white")
canvas.place(x=(1080-width)/2, y=(920-height)/2)
openNum += 1
newNum += 1
if newNum > 1 :
frameDraw.destroy()
frameDraw = Frame()
frameDraw.configure(width=40, height=850, bg='Gray36', bd=1, relief='solid')
frameDraw.pack(side='left', anchor='n')
frameDraw.propagate(0)
buttonPen0 = Button(frameDraw, text="Draw", state='disabled')
buttonPen0.configure(font=('Arial', 9), disabledforeground='white',
bg='Gray26', width=5)
buttonPen1 = Button(frameDraw, text="Color", command=getColor)
buttonPen1.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
buttonPen2 = Button(frameDraw, text="Width", command=getWidth)
buttonPen2.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
buttonPen3 = Button(frameDraw, text="Pen", command=func_pen)
buttonPen3.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
buttonPen0.pack()
buttonPen1.pack()
buttonPen2.pack()
buttonPen3.pack()
buttonShape0 = Button(frameDraw, text="Shape", state='disabled')
buttonShape0.configure(font=('Arial', 9), disabledforeground='white',
bg='Gray26', width=5)
buttonShape1 = Button(frameDraw, text="Line", command=func_line)
buttonShape1.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
buttonShape2 = Button(frameDraw, text="Circle", command=func_circle)
buttonShape2.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
buttonShape3 = Button(frameDraw, text="Rentangle", command=func_rectangle)
buttonShape3.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
buttonShape0.pack()
buttonShape1.pack()
buttonShape2.pack()
buttonShape3.pack()
if openNum > 1 :
fileName.destroy()
fileName = Label(window, text="/New file.png")
fileName.configure(font=('Arial', 10), anchor='nw', fg='white',
width=1350, height=1, padx=10,
bd=1, bg='Gray32', relief='solid')
fileName.pack()
def func_open() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY, openNum, fileName
ask_save()
myFile = askopenfilename(parent=window, filetype=(("JPEG", "*.JPG;*.JPEG;*.JPE"), ("PNG", "*.PNG;*.PNG"), ("CompuServe GIF", "*.GIF"), ("모든 파일", "*.*")))
openNum += 1
if openNum > 1 :
fileName.destroy()
fileName = Label(window, text=myFile)
fileName.configure(font=('Arial', 10), anchor='nw', fg='white',
width=1350, height=1, padx=10,
bd=1, bg='Gray32', relief='solid')
fileName.pack()
photo = Image(filename=myFile)
oriX = photo.width
oriY = photo.height
photo2 = photo.clone()
newX = photo2.width
newY = photo2.height
displayImage(photo, oriX, oriY)
def func_save() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
if photo2 == None :
messagebox.showinfo("오류", "이미지가 없습니다.")
return
saveFile = asksaveasfile(parent=window, mode="w", defaultextension=".png", filetypes=(("JPEG", "*.JPG;*.JPEG;*.JPE"), ("PNG", "*.PNG;*.PNG"), ("CompuServe GIF", "*.GIF"), ("모든 파일", "*.*")))
savePhoto = photo2.convert("png")
savePhoto.save(filename=saveFile.name)
def exit() :
window.quit()
window.destroy()
def func_exit() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
if canvas != None :
response= messagebox.askyesnocancel(title="안내", message="파일을 저장하시겠습니까?")
if response == 1 :
func_save()
exit()
elif response == 0 :
exit()
else :
return
else :
exit()
def error_message() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
if photo2 == None :
messagebox.showinfo("오류", "이미지가 없습니다.")
func_open()
def ask_save() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
if canvas != None :
response= messagebox.askyesnocancel(title="안내", message="아직 저장하지 않은 파일이 존재합니다.\n저장하시겠습니까?")
if response == 1 :
func_save()
return
elif response == 0 :
return
else :
return
else :
return
def func_zoomIn() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
scale = askinteger("확대", "확대할 배수를 입력하세요(2~4)", minvalue=2, maxvalue=4)
photo2.resize(int(newX*scale), int(newY*scale))
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_zoomOut() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
scale = askinteger("축소", "축소할 배수를 입력하세요(2~4)", minvalue=2, maxvalue=4)
photo2.resize(int(newX/scale), int(newY/scale))
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_mirrorW() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
photo2.flip()
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_mirrorH() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
photo2.flop()
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_rotate() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
degree = askinteger("회전", "회전할 각도를 입력하세요", minvalue=0, maxvalue=360)
photo2.rotate(degree)
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_bright() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
value = askinteger("밝게", "값을 입력하세요(0~100)", minvalue=0, maxvalue=100)
photo2.modulate((value+100), 100, 100)
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_dark() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
value = askinteger("어둡게", "값을 입력하세요(0~100)", minvalue=0, maxvalue=100)
photo2.modulate((100-value), 100, 100)
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_saturationH() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
value = askinteger("채도", "값을 입력하세요(0~100)", minvalue=0, maxvalue=100)
photo2.modulate(100, (value+100), 100)
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_saturationL() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
value = askinteger("채도", "값을 입력하세요(0~100)", minvalue=0, maxvalue=100)
photo2.modulate(100, (100-value), 100)
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_bw() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
photo2.type="grayscale"
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_autoZoomIn() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
photo2.resize(int(newX*1.5), int(newY*1.5))
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_autoZoomOut() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
photo2.resize(int(newX/1.5), int(newY/1.5))
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_autoRotate() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
photo2.rotate(90)
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_resetImage() :
global window, canvas, paper, photo, photo2, oriX, oriY, newX, newY
error_message()
photo2 = photo.clone()
newX = photo2.width
newY = photo2.height
displayImage(photo2, newX, newY)
def func_() :
global x1, y1, x2, y2
window = Tk()
window.geometry("1349x880")
window.resizable(False, False)
window.title("Mini Photoshop(Ver2.0)")
mainMenu = Menu(window)
window.config(menu=mainMenu)
window.configure(bg='Gray38')
topImage = PhotoImage(file='./bar.png')
topLabel = Label(window, image=topImage)
topLabel.configure(bd=0)
topLabel.pack(side='top', anchor='w')
rightImage = PhotoImage(file='./box.png')
rightLabel = Label(window, image=rightImage)
rightLabel.configure(bd=0)
rightLabel.pack(side='right', anchor='n')
frame = Frame(master=window)
frame.configure(width=40, height=850, bg='Gray36', bd=1, relief='solid')
frame.pack(side='left', anchor='n')
frame.propagate(0)
icon1 = PhotoImage(file='./icon/zoomin.png')
icon2 = PhotoImage(file='./icon/zoomout.png')
icon3 = PhotoImage(file='./icon/rotate.png')
button0 = Button(frame, text="Tool", state='disabled')
button0.configure(font=('Arial', 9), disabledforeground='white', bg='Gray26',
width=5)
button1 = Button(frame, text="Zoom in", image=icon1, command=func_autoZoomIn)
button1.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
button2 = Button(frame, text="Zoom out", image=icon2, command=func_autoZoomOut)
button2.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
button3 = Button(frame, text="Rotate", image=icon3, command=func_autoRotate)
button3.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
button4 = Button(frame, text="임시", command=func_)
button4.configure(font=('Arial', 9), fg='white', bg='Gray30', cursor='hand2',
bd=1, relief='ridge', overrelief='sunken',
activebackground='Gray28', activeforeground='white')
button0.pack()
button1.pack(padx=2, pady=2)
button2.pack(padx=2, pady=2)
button3.pack(padx=2, pady=2)
button4.pack(padx=2, pady=2)
fileMenu = Menu(mainMenu, tearoff=0, bg='Gray32', fg='white', font='Arial',
activebackground='Gray42')
mainMenu.add_cascade(label="File", menu = fileMenu)
fileMenu.add_separator()
fileMenu.add_command(label="New file", command=func_new)
fileMenu.add_command(label="Open file", command=func_open)
fileMenu.add_command(label="Save file", command=func_save)
fileMenu.add_separator()
fileMenu.add_command(label="Exit", command=func_exit)
fileMenu.add_separator()
image1Menu = Menu(mainMenu, tearoff=0, bg='Gray32', fg='white', font='Arial',
activebackground='Gray42')
mainMenu.add_cascade(label="Edit", menu = image1Menu)
image1Menu.add_separator()
image1Menu.add_command(label="Zoom in", command=func_zoomIn)
image1Menu.add_command(label="Zoom out", command=func_zoomOut)
image1Menu.add_separator()
image1Menu.add_command(label="Mirror width", command=func_mirrorW)
image1Menu.add_command(label="Mirror height", command=func_mirrorH)
image1Menu.add_command(label="Rotate", command=func_rotate)
image1Menu.add_separator()
image2Menu = Menu(mainMenu, tearoff=0, bg='Gray32', fg='white', font='Arial',
activebackground='Gray42')
mainMenu.add_cascade(label="Image", menu = image2Menu)
image2Menu.add_separator()
image2Menu.add_command(label="Bright", command=func_bright)
image2Menu.add_command(label="Dark", command=func_dark)
image2Menu.add_separator()
image2Menu.add_command(label="Saturation high", command=func_saturationH)
image2Menu.add_command(label="Saturation low", command=func_saturationL)
image2Menu.add_separator()
image2Menu.add_command(label="BW", command=func_bw)
image2Menu.add_separator()
image2Menu.add_command(label="Reset image", command=func_resetImage)
image2Menu.add_separator()
window.mainloop()