상세 컨텐츠

본문 제목

[Python 파이썬 독학 활용2편 3일차] GUI(tkinter) - 3-3

파이썬 스터디/파이썬-Python 활용편2

by 후즈테크 2021. 8. 5. 13:38

본문

반응형

25. 자동 스크린 샷

import time

from PIL import ImageGrab # Python Image Libirary
#pip install Pillow


time.sleep(5) # 5초 대기 : 사용자가 준비하는 시간

for i in range(1, 11): # 2초 간격으로 10개 이미지 저장
    img = ImageGrab.grab() # 현재 스크린 이미지를 가져옴
    img.save("image{}.png".format(i)) # 파일로 저장 (iamge1.png - image10.png)
    time.sleep(2) # 2초 단위

주의사항

 - from PIL import ImageGrab 

    : PIL(Python Image Libirary) 사용을 위해 #pip install Pillow 진행

 

26. 이미지 합치기

import os
from tkinter import *
import tkinter.ttk as ttk
import tkinter.messagebox as msgbox
from tkinter import filedialog # 파일 open 기능 사용
from PIL import Image

root = Tk()
root.title("WT GUI")

# 파일 추가
def add_file():
    files = filedialog.askopenfilenames(title ="이미지 파일을 선택하세요", \
        filetypes=(("PNG 파일", "*.png"),("모든 파일", "*.*")), \
            #initialdir="C:/") # 최초에 C:/ 경로를 보여줌
            initialdir=r"D:\personal\study") # 경로 스트링 정상적으로 나옴 탈출 문자 예외

    # 사용자가 선택한 파일 목록
    for file in files:
        list_file.insert(END, file)




# 선택삭제
def del_file():
    # 앞에서 부터 지우면 인덱스번호가 달라짐. 뒤에서 부터 삭제
    for index in reversed(list_file.curselection()):
        list_file.delete(index)


# 저장 경로(폴더)
def browse_dest_path():
    forlder_selected = filedialog.askdirectory()
    if forlder_selected =='':
        return
    #print(forlder_selected)
    txt_dest_path.delete(0, END)
    txt_dest_path.insert(0, forlder_selected)


# 이미지 통합
def merge_image():
    #print(list_file.get(0, END)) # 모든 파일 목록을 가지고 오기
    images = [Image.open(x) for x in list_file.get(0, END)]
    #size -> size[0] : width, size[1] height : 
    widths = [x.size[0] for x in images]
    heights = [x.size[1] for x in images]

    # 최대 넓이, 전체 높이 구해옴
    max_width, total_height = max(widths), sum(heights)
    # print(max_width)
    # print(total_height)

    # 스케치북 준비
    result_img = Image.new("RGB",(max_width, total_height), (255,255,255)) # 배경 흰색
    y_offset = 0 # y 위치 정보

    for img in images:
        result_img.paste(img, (0, y_offset))
        y_offset += img.size[1] # 높이 값 만큼 더해줌

    dest_path = os.path.join(txt_dest_path.get(), "nado_photo.jpg")
    result_img.save(dest_path)

    msgbox.showinfo("알림","작업이 완료되었습니다.")

# 시작
def start():
    # 각 옵션들 값을 확인
    # print("가로 넓이 : ", cmb_width.get())
    # print("간격 : ", cmb_space.get())
    # print("포맷 : ", cmb_format.get())

    # 파일 목록 확인
    if list_file.size() ==0:
        msgbox.showwarning("경고", "이미지 파일을 추가하세요.")
        return
    
    # 저장 경로 확인
    if len(txt_dest_path.get()) ==0:
        msgbox.showwarning("경고", "저장 경로를 선택하세요.")
        return

    #이미지 통합 작업
    merge_image()
    

# # 파일 프레임(파일 추가, 선택 삭제)

file_frame = Frame(root)
file_frame.pack(fill="x", padx=5, pady=5)

btn_add_file = Button(file_frame, padx=5, pady=5, width=12, text ="파일추가", command=add_file)
btn_add_file.pack(side="left")

btn_del_file = Button(file_frame, padx=5, pady=5, width=12, text="선택삭제", command=del_file)
btn_del_file.pack(side="right")

# 리스트 프레임
list_frame = Frame(root)
list_frame.pack(fill="both", padx=5, pady=5)

scrollbar = Scrollbar(list_frame)
scrollbar.pack(side="right", fill="y")

list_file = Listbox(list_frame, selectmode="extended", height=15, yscrollcommand=scrollbar.set)
list_file.pack(side="left", fill="both", expand=True)
scrollbar.config(command=list_file.yview)

# 저장 경로 프레임
path_frame = LabelFrame(root, text="저장경로")
path_frame.pack(fill="x", padx=5, pady=5, ipady=5)

txt_dest_path = Entry(path_frame)
txt_dest_path.pack(side="left", fill="x",padx=5, pady=5,expand=True, ipady=4)

btn_dest_path = Button(path_frame, text="찾아보기", width=10, command=browse_dest_path)
btn_dest_path.pack(side="right", padx=5, pady=5)


# 옵션 프레임
frame_option = LabelFrame(root, text="옵션")
frame_option.pack(padx=5, pady=5, ipady=5)


#1. 가로 넓이 옵션

# 가로 넓이 레이블
lbl_width = Label(frame_option, text ="가로넓이" , width=8)
lbl_width.pack(side="left", padx=5, pady=5)

# 가로 넓이 콤보

opt_width = ["원본유지", "1024", "800", "640"]
cmb_width = ttk.Combobox(frame_option, state="readonly", values = opt_width, width=10)

cmb_width.current(0)
cmb_width.pack(side="left", padx=5, pady=5)


#2. 간격 옵션

# 간격 옵션 레이블

lbl_space = Label(frame_option, text ="간격" , width=8)
lbl_space.pack(side="left", padx=5, pady=5)

# 간격 옵션 콤보
opt_space = ["없음", "좁게", "보통", "넓게"]
cmb_space = ttk.Combobox(frame_option, state="readonly", values = opt_space, width=10)

cmb_space.current(0)
cmb_space.pack(side="left", padx=5, pady=5)



#3. 파일 포맷 옵션

# 파일포맷 옵션 레이블

lbl_format = Label(frame_option, text ="포맷" , width=8)
lbl_format.pack(side="left", padx=5, pady=5)

# 간격 옵션 콤보
opt_format = ["PNG","JPG","BMP"]
cmb_format = ttk.Combobox(frame_option, state="readonly", values = opt_format, width=10)

cmb_format.current(0)
cmb_format.pack(side="left", padx=5, pady=5)


# 진행상황 progress Bar
frame_progress = LabelFrame(root, text="진행상황")
frame_progress.pack(fill="x", padx=5, pady=5, ipady=5)


p_var = DoubleVar()
progress_bar = ttk.Progressbar(frame_progress, maximum=100, variable=p_var)
progress_bar.pack(fill="x", padx=5, pady=5)


# 실행 프레임
frame_run = Frame(root)
frame_run.pack(fill="x", padx=5, pady=5)


btn_close = Button(frame_run, padx=5, pady=5, text="종료", width=12, command=root.quit)
btn_close.pack(side="right", padx=5, pady=5)

btn_start = Button(frame_run, padx=5, pady=5, text="시작", width=12 , command=start)
btn_start.pack(side="right", padx=5, pady=5)



root.resizable(False,False) # x너비, y 변경 불가
root.mainloop()

주의사항

 - merge_image()

    : start 함수 내에 merge_image() 함수를 추가

 - def merge_image():
    #print(list_file.get(0, END)) # 모든 파일 목록을 가지고 오기
    images = [Image.open(x) for x in list_file.get(0, END)]
    widths = [x.size[0] for x in images]
    heights = [x.size[1] for x in images]

    : size 내에 index 번호에 따라 파일의 가로, 세로 값을 저장 /size[0] : width, size[1] height

 

    # 최대 넓이, 전체 높이 구해옴
    max_width, total_height = max(widths), sum(heights)
    : 영상을 합치기 위해 

      가로 : 리스트에 포함된 파일 중 가장 큰 영상

      세로 : 리스트에 포함된 파일 높이의 전체 합

      으로 구성.


    # 스케치북 준비
    result_img = Image.new("RGB",(max_width, total_height), (255,255,255)) # 배경 흰색
    y_offset = 0 

    : 높이(y 위치 정보)를 표기하기 위해 변수 선언

    for img in images:
        result_img.paste(img, (0, y_offset))
        y_offset += img.size[1] # 높이 값 만큼 더해줌

    dest_path = os.path.join(txt_dest_path.get(), "nado_photo.jpg")

    : 파일 저장 경로 : os.path.join(경로,"파일명")

    result_img.save(dest_path)

    : 파일 저장

 

반응형

 

26-2. 이미지 합치기 (progressbar 연동 추가)

import os
from tkinter import *
import tkinter.ttk as ttk
import tkinter.messagebox as msgbox
from tkinter import filedialog # 파일 open 기능 사용
from PIL import Image


root = Tk()
root.title("WT GUI")

# 파일 추가
def add_file():
    files = filedialog.askopenfilenames(title ="이미지 파일을 선택하세요", \
        filetypes=(("PNG 파일", "*.png"),("모든 파일", "*.*")), \
            #initialdir="C:/") # 최초에 C:/ 경로를 보여줌
            initialdir=r"D:\personal\study") # 경로 스트링 정상적으로 나옴 탈출 문자 예외

    # 사용자가 선택한 파일 목록
    for file in files:
        list_file.insert(END, file)




# 선택삭제
def del_file():
    # 앞에서 부터 지우면 인덱스번호가 달라짐. 뒤에서 부터 삭제
    for index in reversed(list_file.curselection()):
        list_file.delete(index)


# 저장 경로(폴더)
def browse_dest_path():
    forlder_selected = filedialog.askdirectory()
    if forlder_selected =='':
        return
    #print(forlder_selected)
    txt_dest_path.delete(0, END)
    txt_dest_path.insert(0, forlder_selected)


# 이미지 통합
def merge_image():
    #print(list_file.get(0, END)) # 모든 파일 목록을 가지고 오기
    images = [Image.open(x) for x in list_file.get(0, END)]
    #size -> size[0] : width, size[1] height : 
    
    
    # widths = [x.size[0] for x in images]
    # heights = [x.size[1] for x in images]

    # zip 이용하여 단순화

    widths, heights = zip(*(x.size for x in images))

    # 최대 넓이, 전체 높이 구해옴
    max_width, total_height = max(widths), sum(heights)
    # print(max_width)
    # print(total_height)

    # 스케치북 준비
    result_img = Image.new("RGB",(max_width, total_height), (255,255,255)) # 배경 흰색
    y_offset = 0 # y 위치 정보

    # for img in images:
    #     result_img.paste(img, (0, y_offset))
    #     y_offset += img.size[1] # 높이 값 만큼 더해줌

    for idx, img in enumerate(images):
        result_img.paste(img, (0, y_offset)) 
        y_offset += img.size[1] # 높이 값 만큼 더해줌       

        progress = (idx + 1) / len(images) *100 # 실제 percent 정보를 계산 / index 0 부터 시작
        p_var.set(progress)
        progress_bar.update()


    dest_path = os.path.join(txt_dest_path.get(), "nado_photo.jpg")
    result_img.save(dest_path)

    msgbox.showinfo("알림","작업이 완료되었습니다.")

# 시작
def start():
    # 각 옵션들 값을 확인
    # print("가로 넓이 : ", cmb_width.get())
    # print("간격 : ", cmb_space.get())
    # print("포맷 : ", cmb_format.get())

    # 파일 목록 확인
    if list_file.size() ==0:
        msgbox.showwarning("경고", "이미지 파일을 추가하세요.")
        return
    
    # 저장 경로 확인
    if len(txt_dest_path.get()) ==0:
        msgbox.showwarning("경고", "저장 경로를 선택하세요.")
        return

    #이미지 통합 작업
    merge_image()
    

# # 파일 프레임(파일 추가, 선택 삭제)

file_frame = Frame(root)
file_frame.pack(fill="x", padx=5, pady=5)

btn_add_file = Button(file_frame, padx=5, pady=5, width=12, text ="파일추가", command=add_file)
btn_add_file.pack(side="left")

btn_del_file = Button(file_frame, padx=5, pady=5, width=12, text="선택삭제", command=del_file)
btn_del_file.pack(side="right")

# 리스트 프레임
list_frame = Frame(root)
list_frame.pack(fill="both", padx=5, pady=5)

scrollbar = Scrollbar(list_frame)
scrollbar.pack(side="right", fill="y")

list_file = Listbox(list_frame, selectmode="extended", height=15, yscrollcommand=scrollbar.set)
list_file.pack(side="left", fill="both", expand=True)
scrollbar.config(command=list_file.yview)

# 저장 경로 프레임
path_frame = LabelFrame(root, text="저장경로")
path_frame.pack(fill="x", padx=5, pady=5, ipady=5)

txt_dest_path = Entry(path_frame)
txt_dest_path.pack(side="left", fill="x",padx=5, pady=5,expand=True, ipady=4)

btn_dest_path = Button(path_frame, text="찾아보기", width=10, command=browse_dest_path)
btn_dest_path.pack(side="right", padx=5, pady=5)


# 옵션 프레임
frame_option = LabelFrame(root, text="옵션")
frame_option.pack(padx=5, pady=5, ipady=5)


#1. 가로 넓이 옵션

# 가로 넓이 레이블
lbl_width = Label(frame_option, text ="가로넓이" , width=8)
lbl_width.pack(side="left", padx=5, pady=5)

# 가로 넓이 콤보

opt_width = ["원본유지", "1024", "800", "640"]
cmb_width = ttk.Combobox(frame_option, state="readonly", values = opt_width, width=10)

cmb_width.current(0)
cmb_width.pack(side="left", padx=5, pady=5)


#2. 간격 옵션

# 간격 옵션 레이블

lbl_space = Label(frame_option, text ="간격" , width=8)
lbl_space.pack(side="left", padx=5, pady=5)

# 간격 옵션 콤보
opt_space = ["없음", "좁게", "보통", "넓게"]
cmb_space = ttk.Combobox(frame_option, state="readonly", values = opt_space, width=10)

cmb_space.current(0)
cmb_space.pack(side="left", padx=5, pady=5)



#3. 파일 포맷 옵션

# 파일포맷 옵션 레이블

lbl_format = Label(frame_option, text ="포맷" , width=8)
lbl_format.pack(side="left", padx=5, pady=5)

# 간격 옵션 콤보
opt_format = ["PNG","JPG","BMP"]
cmb_format = ttk.Combobox(frame_option, state="readonly", values = opt_format, width=10)

cmb_format.current(0)
cmb_format.pack(side="left", padx=5, pady=5)


# 진행상황 progress Bar
frame_progress = LabelFrame(root, text="진행상황")
frame_progress.pack(fill="x", padx=5, pady=5, ipady=5)


p_var = DoubleVar()
progress_bar = ttk.Progressbar(frame_progress, maximum=100, variable=p_var)
progress_bar.pack(fill="x", padx=5, pady=5)


# 실행 프레임
frame_run = Frame(root)
frame_run.pack(fill="x", padx=5, pady=5)


btn_close = Button(frame_run, padx=5, pady=5, text="종료", width=12, command=root.quit)
btn_close.pack(side="right", padx=5, pady=5)

btn_start = Button(frame_run, padx=5, pady=5, text="시작", width=12 , command=start)
btn_start.pack(side="right", padx=5, pady=5)



root.resizable(False,False) # x너비, y 변경 불가
root.mainloop()

주의사항

 - for idx, img in enumerate(images):
        result_img.paste(img, (0, y_offset)) 
        y_offset += img.size[1] # 높이 값 만큼 더해줌       

        progress = (idx + 1) / len(images) *100 # 실제 percent 정보를 계산 / index 0 부터 시작
        p_var.set(progress)
        progress_bar.update()

    : progress 바와 연동 images의 갯수의 100분률을 계산해 반영. 

반응형

관련글 더보기

댓글 영역