ChatGPT4로만 코딩하기 – Webp 이미지 변환 프로그램(png, jpeg, jpg to webp) 만들어보기

  • Post author:

워드프레스를 사용하다보면, Smush, EWWW같은 이미지 최적화 플러그인 등을 사용한다. 특히 EWWW같은 경우는 png나 jpeg파일을 올리면 자동으로 webp로 변환시켜주는 기능을 가지고 있다. 그러나 서버에 저장되는 것은 png, jpeg이고, 사용자에게 보여주는 이미지만 webp로 보여지는 것이기에, 처음 업로드할 때부터 webp로 올리면 서버 스토리지 용량도 절약할 수 있게 된다.

기존까지는 무료 변환 웹사이트인 AnyConv같은 사이트를 이용했지만, 이 사이트를 이용하는 대신, 요즘 열심히 배우고 있는 파이썬으로 자동 변환 프로그램을 만들면 좋지 않을까? 생각하여, GPT4를 이용하여 코딩하기 시작했다. 이 게시글은 GPT4를 이용하여 코딩하는 과정을 보여주고, 그 결과를 공유하려 한다.

Step1. 일단 뭔가 만들어 줘.

질문1

나는 뤼튼(wrtn.ai)을 이용하여 Chatgpt4를 사용했다. 이 사이트에서는 무료로 gpt4를 이용할 수 있어 추천한다. 나는 파이썬의 아주 기초는 알고 있고 라이브러리를 사용해서 이 프로그램을 만들어야 한다는 사실을 알고 있었기에, 아래와 같이 질문했고, GPT가 코딩을 해주었다.

파이썬 Pillow라이브러리를 이용해서 png, jpeg 파일 등을 WebP 파일로 변환하는 프로그램을 만들고 싶어. exe파일로 포팅까지 하고싶은데 어떻게 해야해? exe파일을 실행시키면 드래그앤 드롭으로 png, jpeg 파일을 드래그앤 드롭할 수 있고, 변환 버튼 누르면 webp로 변환해서 exe파일 내에서 적은 경로에 자동으로 저장하게 만들었으면 좋겠어.

그래서 받은 답변은 뭔가 맥이 빠지고, 전체 코드를 만들어 준 것 같지도 않고 딱 보니 변환하는 함수만을 생성해주었을 뿐, 드래그앤 드롭이나 여러가지 기능의 추가가 필요했다. 따라서 GPT에게 계속해서 말을 걸어본다.

질문2

바로.. 종합적으로 모든 코드를 작성해줘! 라고 하니 여러 라이브러리를 설치하는 파이썬 코드를 만들더니, 나에게 보여주었다.

그런데 드래그앤 드롭 기능을 추가하고 싶었고, 여러 파일을 한번에 처리하는 기능을 추가하고 싶었기에 아래와 같이 또 질문했다.

음 좋아. 저렇게 하면 드래그앤드롭으로 파일을 여러개 설정할수도 있어? 한번에 여러개의 파일을 집어넣을 수도 있잖아. list 등을 따로 추가해서 for 문으로 하나하나 차근차근 변환시켜야 할 것 같은데 그게 되는건지 궁금해. 그리고 파일을 변환해서 저장할 주소를 묻는 gui가 따로 없는 것 같은데, 추가해줘

그랬더니 파일을 변환해서 저장할 수 있는 주소를 묻는 gui를 추가해서 GPT가 코드를 뱉었는데, 아래와 같은 코드가 내 눈에 거슬렸다.

1
2
3
4
def set_output_dir():
    global output_dir
    output_dir = filedialog.askdirectory()
    messagebox.showinfo(“안내”, f“파일이 저장될 경로: {output_dir}”)
cs

이 코드는 messagebox를 통해 파일이 저장될 경로를 만들어주는 것이었는데, 프로그램이 실행될 때 메시지 박스가 뜨면 좀 당황스러울 것 같아, 흔히들 사용하는 경로 선택하는 기능으로 바꿔달라고 했다.

음 지금 너가 말해준 코드는 메시지 박스를 이용해서 프로그램을 실행했을 때 한번만 볼 수 있는데 그렇게 말고, 상시 존재하는 입력창을 만들어서 거기에 입력할 수 있게 만들어줘. 그리고 내가 드래그앤 드롭으로 파일을 올리면, gui에 파일명이 전부다 보였으면 좋겠어.

GPT는 정말 똑똑하다. 내가 그냥 이상하게 말한 것을 찰떡같이 알아먹고 경로 선택하기 기능을 메시지 박스가 아닌 버튼을 만들어서 수정해주었다. 대충 이렇게 구동은 되게 만들어두었으니, 코드를 대충보고 없는 기능을 추가할 차례다.

Step2. 여러가지 기능을 더 추가하고 다듬기

3

먼저 변환전 png나 jpeg의 파일 리스트도 프로그램 상에 나올 수 있도록 요청했더니 이 기능을 추가해줬다.

4

그 다음에는 ‘초기화’ 버튼을 추가해달라고 GPT에게 부탁했다. 한 장 한 장 변환할 때마다 프로그램을 껐다 켤 순 없기 때문이다.

5

그리고.. 나 같은 경우에는 이 프로그램을 만들면서 공부하고자 했기 때문에, 프로그램 코드에 하나하나 주석을 달아달라고 했다. 그랬더니..

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# 필요한 모듈들을 불러옵니다.
import os
import tkinter as tk
from tkinterdnd2 import DND_FILES, TkinterDnD
from tkinter import messagebox, filedialog, StringVar
from PIL import Image
 
# 출력 디렉토리 (변환된 파일이 저장될 경로)를 전역 변수로 선언합니다.
output_dir = 
 
# ‘저장 경로 설정’ 버튼을 눌렀을 때 호출되는 함수입니다.
def set_output_dir():
    global output_dir
    # 파일 대화상자를 열어 사용자로부터 디렉토리를 선택받습니다.
    output_dir = filedialog.askdirectory()
    # 선택받은 디렉토리를 라벨에 표시합니다.
    dir_var.set(f“선택된 저장 경로: {output_dir}”)
 
# 파일을 드래그 앤 드롭했을 때 호출되는 함수입니다.
def drop(event):
    # 출력 디렉토리가 설정되지 않았다면 오류 메시지를 표시하고 함수를 종료합니다.
    if not output_dir:
        messagebox.showerror(“경로 오류”“파일을 저장할 경로를 먼저 설정해주세요.”)
        return
    
    # 드래그 앤 드롭한 파일들의 경로를 가져옵니다.
    file_paths = root.drop_source(event)
    # 각 파일에 대해
    for file_path in file_paths:
        # 파일이 png, jpeg, jpg 중 하나의 형식이라면
        if file_path.lower().endswith((‘.png’‘.jpeg’‘.jpg’)):
            # 업로드된 파일 리스트에 파일 이름을 추가합니다.
            listbox_upload.insert(tk.END, os.path.basename(file_path))
            # 이미지 파일을 열어 PIL 이미지 객체를 생성합니다.
            img = Image.open(file_path)
            # 출력 디렉토리와 변환된 파일의 이름을 결합하여 출력 경로를 생성합니다.
            output_path = os.path.join(output_dir, os.path.splitext(os.path.basename(file_path))[0+ ‘.webp’)
            # 이미지를 webp 형식으로 변환하여 출력 경로에 저장합니다.
            img.save(output_path, ‘webp’)
            # 변환된 파일 리스트에 변환된 파일 이름을 추가합니다.
            listbox_converted.insert(tk.END, os.path.splitext(os.path.basename(file_path))[0+ ‘.webp’)
        # 파일이 허용된 형식이 아니라면 오류 메시지를 표시합니다.
        else:
            messagebox.showerror(“파일 오류”“허용되지 않은 파일 형식입니다.”)
 
# ‘초기화’ 버튼을 눌렀을 때 호출되는 함수입니다.
def clear_listboxes():
    # 업로드된 파일 리스트와 변환된 파일 리스트를 모두 비웁니다.
    listbox_upload.delete(0, tk.END)
    listbox_converted.delete(0, tk.END)
 
# TkinterDnD를 사용하여 드래그 앤 드롭 기능이 활성화된 창을 생성합니다.
root = TkinterDnD.Tk()
# 창을 일시적으로 숨깁니다.
root.withdraw()
# 창의 제목을 설정합니다.
root.title(‘이미지 변환기’)
# 창에 드래그 앤 드롭 이벤트를 등록합니다.
root.drop_target_register(DND_FILES)
root.dnd_bind(‘<<Drop>>’, drop)
 
# ‘저장 경로 설정’ 버튼을 생성하고 창에 추가합니다.
dir_button = tk.Button(root, text=“저장 경로 설정”, command=set_output_dir)
dir_button.pack()
 
# ‘초기화’ 버튼을 생성하고 창에 추가합니다.
clear_button = tk.Button(root, text=“초기화”, command=clear_listboxes)
clear_button.pack()
 
# 저장 경로를 표시할 라벨을 생성하고 창에 추가합니다.
dir_var = StringVar()
dir_label = tk.Label(root, textvariable=dir_var)
dir_label.pack()
 
# 업로드된 파일 리스트를 표시할 리스트 박스를 생성하고 창에 추가합니다.
listbox_upload = tk.Listbox(root)
listbox_upload.pack()
tk.Label(root, text=“업로드된 파일”).pack()
 
# 변환된 파일 리스트를 표시할 리스트 박스를 생성하고 창에 추가합니다.
listbox_converted = tk.Listbox(root)
listbox_converted.pack()
tk.Label(root, text=“변환된 파일”).pack()
 
# 창을 다시 보이게 합니다.
root.deiconify()
# 창의 메인 이벤트 루프를 시작합니다.
root.mainloop()
cs

상당히 친절하게 하나하나 주석을 달아주었다. 그런데 그리고 마지막으로 ‘변환’ 버튼을 추가해달라고 했다.

6

그리고 GPT가 알려준 코드를 실행했더니, 아니나 다를까 오류가 뜬다. 오류 내용을 말하면서 왜 그런지 물어보니, 기가막히게 오류가 난 부분을 찾아 수정해준다.

7

정말 신기하다. 난 파이썬에 대한 기초적인 문법 정도만 알고 뭐 pillow니, tkinter이니 이런 라이브러리를 모르지만 그냥 GPT가 알아서 다 짜주고, 내가 원하는 기능도 만들어주고, 주석도 친절히 달아줬다. 주석을 보면서 ‘변환’버튼 추가해달라니 또 잘해준다.

최종 결과물 확인하기 – png, jpg, jpeg to Webp

결국 오류를 수정하고 안되는 라이브러리를 제외하고, 잘 돌아가는 최종 결과물은 다음과 같다. 이 게시글에 exe파일까지는 서버 용량 문제로 올릴 수는 없다. 이 코드를 vscode를 실행하여 복사한 뒤, 터미널창에 pip install tkinter, pip install pillow, pip install pyinstaller를 차례대로 입력한 뒤, pyinstaller -F OOOO.py 를 입력하면 exe파일로 자동으로 포팅이 될 것이다. 그리고 어차피 이 프로그램 말고도, 인터넷 검색하다보면 이 기능과 똑같은 프로그램이 많으니 그것을 사용하면 된다.

<–>(231205 추가) 해당 기능과 워터마크 삽입 기능을 추가하여 코드를 공유하니, 이 링크를 통해 추가된 코드를 확인하시기 바란다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import os
import tkinter as tk
from tkinter import messagebox, filedialog, StringVar
from PIL import Image
 
output_dir = 
file_paths = []
 
def set_output_dir():
    global output_dir
    output_dir = filedialog.askdirectory()
    dir_var.set(f“선택된 저장 경로: {output_dir}”)
 
def select_files():
    global file_paths
    file_paths = filedialog.askopenfilenames(filetypes=[(‘Image files’‘.png .jpeg .jpg’)])
    for file_path in file_paths:
        listbox_upload.insert(tk.END, os.path.basename(file_path))
 
def convert_images():
    if not output_dir:
        messagebox.showerror(“경로 오류”“파일을 저장할 경로를 먼저 설정해주세요.”)
        return
    for file_path in file_paths:
        img = Image.open(file_path)
        output_path = os.path.join(output_dir, os.path.splitext(os.path.basename(file_path))[0+ ‘.webp’)
        img.save(output_path, ‘webp’)
        listbox_converted.insert(tk.END, os.path.splitext(os.path.basename(file_path))[0+ ‘.webp’)
 
def clear_listboxes():
    listbox_upload.delete(0, tk.END)
    listbox_converted.delete(0, tk.END)
 
root = tk.Tk()
root.title(‘이미지 변환기’)
root.geometry(‘800×600’)
 
dir_button = tk.Button(root, text=“저장 경로 설정”, command=set_output_dir)
dir_button.pack()
 
select_button = tk.Button(root, text=“파일 선택”, command=select_files)
select_button.pack()
 
convert_button = tk.Button(root, text=“변환”, command=convert_images)
convert_button.pack()
 
clear_button = tk.Button(root, text=“초기화”, command=clear_listboxes)
clear_button.pack()
 
dir_var = StringVar()
dir_label = tk.Label(root, textvariable=dir_var)
dir_label.pack()
 
listbox_upload = tk.Listbox(root)
listbox_upload.pack()
tk.Label(root, text=“업로드된 파일”).pack()
 
listbox_converted = tk.Listbox(root)
listbox_converted.pack()
tk.Label(root, text=“변환된 파일”).pack()
 
root.mainloop()
 
cs

이 코드를 실행하니 프로그램이 실행이 되었다.

최종 결과물

정말 신기하게도 잘 실행되고 오류가 나는 부분이 하나도 없이 잘 구동이 되었다. gui도 꾸밈없고 정말 아무것도 없지만 기능만 잘 되면 된다. 속도도 엄청나게 빠르다. webp로 변환이 되니 이미지 용량도 거의 1/7 수준으로 줄어들었다. 너무 만족스럽다. 이렇게 gpt만 써서 코딩이 되는 시대라니.. 정말 기술의 발전이 대단한 것 같다. 궁금한 점 있으면 댓글로 남겨주면 답변드릴 수 있도록 하겠다. 끝!

답글 남기기