
파이썬으로 작성한 코드를 exe 파일로 만드는 방법에 pyinstaller 라이브러리가 사용된다.
pyinstaller는 여러가지 옵션들을 지원하는데, 대표적으로 많이 사용되는 옵션은 --onefile --windowed -icon --add-data --add-binary 정도로 말할 수 있을 것 같다.
최근에 이미지 파일을 webp 확장자 이미지로 변환하는 간단한 프로그램을 만들고 GUI 로 사용하기 위해 PyQt를 사용해서 GUI를 만들었다.
만들고 다른 사람들에게도 공유하고 싶어서 exe 파일로 만들기 위해 이것저것 pyinstaller를 찾아보고 사용해봤는데 다른건 괜찮은데 아이콘 적용이 안돼서 곤욕을 치루다가 해결해서 작성하는 블로그이다...
우선 내가 만든 프로그램은 webp로 변환을 해야하기 때문에 webp 확장자를 만든 구글이 배포하는 cwebp 파일이 필요하다.
이 파일은 이미지를 webp로 바꾸어주는 파일로 내 GUI 실행파일에 번들링을 하였다.
그리고 프로그램의 아이콘을 지정하기 위해서 아이콘 파일도 번들링해야했다.
참고로 pyinstaller는 pip install pyinstaller로 설치가능하다.
pyinstaller로 빌드와 번들링을 위해 사용한 터미널 명령어는 다음과 같다.
pyinstaller --windowed --onefile --add-binary "cwebp;." --add-binary "cwebp.exe;." --add-b
inary "icon.ico;." -i icon.ico ImageToWebp.py
하나씩 설명하자면
--windowed GUI 프로그램을 위해서 사용, 프로그램을 실행할때 콘솔창이 뜨지 않게 하는 용도
--onefile 실행파일을 하나로 만들기 위해서 사용
--add-binary "cwebp.exe;." 번들링을 위해서 사용, 이 프로그램에서는 cwebp.exe 파일을 번들링하기 위해서 사용
--add-binary "{번들링할 파일};{번들링된 파일의 위치}" 로 사용한다.
여기서 주의해야할 것은 번들링할 파일과 번들링된 파일의 위치 사이의 세미콜론(;) 을 사용했는데, Mac에서 pyinstaller를 사용하려면 세미콜론(;) 대신 콜론(:)을 사용해야한다.
--add-binary "icon.ico;." 이건 프로그램이 실행되고 왼쪽 위의 프로그램 아이콘을 설정하기 위해 사용했다.

-i icon.ico 이건 실행파일 자체의 아이콘을 지정하기 위해 사용

아이콘을 아무리 번들링해도 적용이 되지 않았는데 pyinstaller를 사용하고 나면 build랑 dist같은 폴더들이 생기는데 dist에 실행파일이 생긴다.
그냥 아이콘 적용이 안된 실행파일을 바깥으로 빼니깐 적용이되었다..?

..?

--add-binary "icon.ico;."
이런 방식으로 번들링한 파일을 코드에서 직접 사용하려면 아래와 같이 해야한다.
icon_path = os.path.join(os.path.dirname(__file__), 'icon.ico')
# icon_path = './icon.ico' 이런식으로 사용하면 적용이 안된다.
# 단순히 IDE에서 실행시키면 보이긴하는데, 실행파일을 만들고 실행하면
# 번들링이 된 실행파일을 기준으로 하기 때문인듯..?
def is_macos():
system_info = platform.system()
return system_info == "Darwin"
if(is_macos()):
print('이 운영체제는 맥입니다.')
cwebp_path = os.path.join(os.path.dirname(__file__), 'cwebp')
else:
print('이 운영체제는 윈도우입니다.')
cwebp_path = os.path.join(os.path.dirname(__file__), 'cwebp.exe')
깃허브에 올려뒀다. 필요한 분들은 릴리즈에서 받아가면 됩니다.
깃허브 링크
프로젝트 안의 dist 폴더에서 OS에 맞게 사용하면 됩니다.
이미지 파일 단일 혹은 다수 선택 후 확인을 누르면 이미지파일이 있는 폴더에 "변환된 이미지" 폴더가 생기고, 그 안에 저장됩니다.
압축률은 25 정도인데, 선택가능하게 업데이트할 예정입니다.