ABOUT ME

IT와 컴퓨터 관련 팁, 파이썬 등과 아파트 정보, 일상적인 경험 등의 생활 정보를 정리해서 올리는 개인 블로그

  • 이미지 병합 - 파이썬 Tkinter 활용
    코딩 연습 2022. 12. 28. 00:00
    반응형

    이미지 병합 프로그램이 필요하여 유튜브 검색 중 나도코딩 유튜버님의 영상을 보고 따라하면서 만든 소스 코드이며, pyinstaller로 실행 프로그램을 생성해보았다.

     

     

    이미지 병합해주는 프로그램(파이썬 tkinter & pyinstaller 라이브러리 활용)

    이미지 병합 프로그램
    이미지 병합 프로그램

    프로그램 다운로드

    (네이버 MyBox 다운로드 비번: 1234)

     

    ▷ 파이썬 Tkinter 소스코드는 다음과 같다.

    ## 이미지를 원본 그대로 붙여서 저장하기
    
    import os
    import time
    import tkinter.ttk as ttk  # 콤보박스
    import tkinter.messagebox as msgbox
    from tkinter import *
    from tkinter import filedialog
    from PIL import Image
    
    
    root = Tk()
    root.title('Image Merger')
    root.geometry('450x510+700+100')
    root.resizable(False, False)
    
    ## 파일 추가 함수
    def add_file():
        files = filedialog.askopenfilenames(
            title='이미지 파일을 선택하세요.',
            filetypes=(('JPG 파일', '*.jpg'), ('PNG 파일', '*.png'), ('BMP 파일', '*.bmp'), ('모든 파일', '*.*')),
            initialdir='./')
    
        for file in files:
            # 리스트 영역에 파일명 insert 
            list_file.insert(END, file)
    
    
    ## 선택 파일 삭제 함수
    def del_file():
        for idx in reversed(list_file.curselection()):  # 리스트 요소 뒤집기
            list_file.delete(idx)
    
    
    ## 저장 경로 폴더(Path)
    def browse_dest_path():
        folder_selected = filedialog.askdirectory()
    
        # 사용자가 폴더 선택 안하고(취소) 파일 선택창을 닫았을 때
        if folder_selected == '':  # 또는 not folder_selected
            return
    
        # disable -> normal -> disable 순서로 상태값 변경
        txt_dest_path.configure(state='normal')
        txt_dest_path.delete(0, END) 
        txt_dest_path.insert(0, folder_selected)
        txt_dest_path.configure(state='disable')
    
    
    ## 이미지 통합 
    def merge_image():
        try:
            images = [Image.open(x) for x in list_file.get(0, END)]
            widths = [x.size[0] for x in images]  # 이미지의 width 리스트
            heights = [y.size[1] for y in images]  # 이미지의 height 리스트
            max_width, total_height = max(widths), sum(heights)
    
            # 이미지를 병합할 새 스케치북 준비 ('RGB, (가로크기, 세로크기), 배경색)
            result_img = Image.new('RGB', (max_width, total_height), (255, 255, 255))
            y_offset = 0 
    
            for idx, img in enumerate(images):
                result_img.paste(img, (0, y_offset))
                y_offset += img.size[1]
    
                # 이미지 순번 / 전체 이미지수 = 진행 비율 (100% 대비 진행률)
                progress = (idx + 1) / len(images) * 100
                p_var.set(progress)
                progress_bar.update()
    
            # 병합된 이미지 저장하기
            current_time = time.strftime('%Y%m%d%H%M%S')
            dest_path = os.path.join(txt_dest_path.get(), f'image_merge_{current_time}.jpg')
            result_img.save(dest_path)
            msgbox.showinfo('알림', '이미지 병합 작업이 완료되었습니다!!')
    
        except Exception as e:
            msgbox.showerror('에러', e)
    
    
    ## 실행 - 시작
    def start():
        # 파일 목록 확인
        if not list_file.size():
            msgbox.showwarning('경고', '이미지 파일을 선택하여 추가하세요.')
            return
    
        # 저장 경로 확인
        if not len(txt_dest_path.get()):
            msgbox.showwarning('경고', '저장 경로를 선택하세요.')
            return
    
        # 이미지 병합 작업 함수 호출
        merge_image()
    
    
    ## 파일 프레임 (파일 추가, 선택 파일 삭제)
    file_frame = Frame(root)
    file_frame.pack(fill='x', padx=5, pady=5)
    
    # 버튼
    btn_add_file = Button(file_frame, text='파일 추가', padx=5, pady=5, width=12, command=add_file)
    btn_add_file.pack(side='left')
    btn_del_file = Button(file_frame, text='선택 삭제', padx=5, pady=5, width=12, 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')
    
    # 리스트 박스(선택 모드, 높이 15, 우측에 스크롤바 세팅 맵핑)
    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', expand=True, padx=5, pady=5, ipady=4)  # ipad : 입력칸 높이
    txt_dest_path.configure(state='disable')
    
    # 찾아보기 버튼
    btn_dest_path = Button(path_frame, text='찾아보기', width=10, command=browse_dest_path)
    btn_dest_path.pack(side='right', 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_start = Button(frame_run, text='닫기', width=12, padx=5, pady=5, command=root.quit)
    btn_start.pack(side='right', padx=5, pady=5)
    btn_start = Button(frame_run, text='시작', width=12, padx=5, pady=5, command=start)
    btn_start.pack(side='right', padx=5, pady=5)
    
    
    root.mainloop()

     

    good4me.co.kr

     

    ▷ 소스 코드 설명

     

     

    [출처] 파이썬 코딩 무료 강의 (활용편2) - GUI 프로그래밍을 배우고 '여러 이미지 합치기' 프로그램을 함께 만들어요. [나도코딩]

    ※ 영상 2:09:25 부분부터 이미지 병합 프로젝트 시작됨

     

     

     

    반응형
Designed by goodthings4me.