포트폴리오
프로젝트 목록
이미지 한 장을 언어별로 다시 만드는 일 상세페이지나 홍보 이미지를 해외용으로 바꿔야 할 때가 많았다. 문장 몇 줄을 바꾸는 일처럼 보이지만 실제 작업은 꽤 길다. 포토샵에서 원문 글자를 하나씩 지우고, 지운 자리의 배경을 주변 색이나 패턴에 맞춰 메우고, 번역문을 다시 얹은 뒤 크기와 위치를 맞춘다. 언어가 하나 늘 때마다 이 과정을 처음부터 반복해야 했다. 그래서 이 반복 작업을 프로그램으로 옮기기로 했다. 목표는 "이미지 한 장을 넣으면 번역된 PSD가 나온다"였다. 완성 이미지가 아니라 PSD로 정한 데는 이유가 있다. 자동 번역과 자동 배경 복원이 100% 맞을 수는 없으니, 사람이 마지막에 레이어 단위로 손볼 수 있어야 실제 업무에 쓸 수 있다고 봤다. 이 시리즈는 그 과정을 세 편으로 나눠 정리한다. 1편에서는 처음 만든 반자동 도구가 왜 부족했는지와 두 번째 프로그램의 전체 구조를 다루고, 2편에서는 OCR 결과를 문장 단위로 다시 맞추는 문제와 번역 검증을, 3편에서는 원문 제거와 PSD 생성을 다룬다. 첫 번째 도구: 사람이 영역을 지정하는 방식 처음 만든 것은 Tkinter로 만든 작은 OCR 번역 도구였다. 화면 왼쪽에 원본 이미지, 가운데에 결과 이미지를 두고, 사용자가 번역할 영역을 사각형이나 다각형으로 직접 그린다. 그 영역을 잘라 Google Cloud Vision으로 OCR을 돌리고, DeepL로 번역한 다음, 영역을 배경색으로 칠하고 번역문을 Pillow로 그려 넣는 구조였다. 번역 언어: 영어(EN-US), 독일어, 프랑스어, 일본어, 한국어 5개 배경 처리: 이미지 전체의 중앙값 색을 배경색으로 쓰거나, 사용자가 결과 이미지에서 클릭해 색을 고름 배경 제거: 영역 중심점에서 floodfill(..., thresh=30) 로 비슷한 색을 채움 위치 보정: 폰트 크기(8~72)와 X/Y 오프셋(-50~50)을 사용자가 스핀박스로 조절 써 보니 한계가 분명했다. 영역을 사람이 지정해야 하니 문장이 많은 상세페이지에서는 영역 그리기만으로 시간이 꽤 걸렸다. 배경은 단색 칠하기라 그라데이션이나 사진 위에 올라간 글자에서는 네모난 자국이 그대로 보였다. 결과물이 평면 PNG/JPG라서 번역문 한 줄을 고치려면 처음부터 다시 적용해야 했다. 우클릭으로 영역을 지우는 기능에서는 x좌표를 x0 <= event.x <= y0 처럼 y값과 비교하는 버그도 있었는데, 나중에 코드를 정리하면서 x1 로 고쳤다. 결국 이 도구는 "사람이 할 일을 조금 줄여 주는" 수준에 머물렀다. 영역 지정, 배경 처리, 결과 수정이라는 세 가지 수작업을 모두 없애야 했고, 그게 두 번째 프로그램의 출발점이 됐다. 요구사항과 제약 두 번째 프로그램에서 정한 요구사항은 다음과 같았다. 영역을 사람이 지정하지 않는다. OCR이 돌려주는 좌표로 문장 위치를 자동으로 잡는다. 번역 언어를 5개에서 30개 이상으로 늘린다. 원문을 지운 자리가 배경과 어울려야 한다. 아이콘이나 로고는 건드리면 안 된다. 결과는 원본, 원문 제거본, 번역 텍스트가 레이어로 나뉜 PSD로 저장한다. 이미 만들어진 PSD/PSB가 있으면 텍스트 레이어만 바로 번역한다. 여러 사람이 쓰므로 로그인, 포인트 차감, 사용 내역을 관리한다. 제약도 있었다. PSD를 만들려면 Photoshop을 직접 조작해야 했고, 그 방법은 Windows COM 자동화뿐이었다. 그래서 처음부터 Windows 전용 프로그램이 됐다. 외부 API를 네 종류(Vision, OpenAI, Gemini, Photoshop COM)나 엮다 보니 어느 한 곳이 실패해도 전체 작업이 멈추지 않게 하는 처리가 필요했다. 전체 구조 프로그램은 index_psd_trans.py 하나에 UI와 로직이 모두 들어 있는 Tkinter 앱이다. 일반 이미지를 넣었을 때의 흐름은 이렇다. 단계 담당 하는 일 텍스트 감지 Google Cloud Vision 단어 단위 좌표와 전체 텍스트 추출, 줄 그룹으로 묶어 문장 위치 계산 번역 OpenAI GPT-4o 문장 단위 번역, 원문 문자 잔존 검사 후 재시도 원문 제거 OpenCV + Gemini OpenCV 인페인팅 후 텍스트 영역만 Gemini 결과로 보정 PSD 생성 Photoshop COM 원본 위에 제거본 레이어를 붙이고, 번역문을 텍스트 레이어 그룹으로 추가 기록 MySQL 포인트 차감, 사용 내역과 완료 여부 저장 번역 엔진을 DeepL에서 GPT-4o로 바꾼 것은 언어 수와 규칙 때문이었다. 30개 이상의 언어를 하나의 API로 다루고 싶었고, "마더케이는 항상 Mother-K로", "줄바꿈 수는 원문과 같게" 같은 규칙을 프롬프트로 강제할 수 있다는 점이 컸다. 대신 결과가 매번 같지 않다는 문제가 생겼는데, 이 부분은 2편에서 다룬다. PSD/PSB 파일은 경로가 다르다. 이미지 처리 없이 Photoshop으로 파일을 열고, 레이어 그룹을 재귀로 돌면서 텍스트 레이어의 내용만 번역해 새 이름으로 저장한다. 시행착오: 스레드에서 Photoshop을 부르면 멈춘다 작업 시간이 길어서 번역은 처음부터 별도 스레드로 돌렸다. UI가 멈추지 않게 하려는 것이었다. 그런데 드래그 앤 드롭으로 파일을 받고 PSD 크기를 백그라운드에서 읽도록 바꾼 무렵, 번역 스레드에서 Photoshop COM 객체를 만들 때 오류가 났다. 원인은 COM의 스레드 규칙이었다. COM은 객체를 쓰는 스레드마다 초기화가 필요한데, 메인 스레드는 Tkinter와 pywin32가 알아서 처리해 주지만 새로 만든 스레드는 그렇지 않다. 그래서 번역 스레드 진입점인 main() 맨 앞에 pythoncom.CoInitialize() 를 넣고, 정상 종료와 오류 종료 경로마다 CoUninitialize() 를 넣었다. def main(): image_path = file_path_entry.get() if not image_path: return # 스레드에서 COM 사용을 위한 초기화 pythoncom.CoInitialize() try: ... # OCR → 번역 → 원문 제거 → PSD 생성 except pywintypes.com_error as e: if e.args[0] == -2147417846: # 작업 중 사용자가 Photoshop을 건드린 경우 messagebox.showerror(t("err_ps_title"), t("err_ps_touch")) ... pythoncom.CoUninitialize() return ... pythoncom.CoUninitialize() 또 하나 자주 나던 오류가 있었다. 작업 중에 사용자가 Photoshop 창을 클릭하거나 다른 작업을 하면 COM 호출이 거부되면서 -2147417846 오류가 났다. 코드로 막을 수 있는 문제가 아니어서, 이 코드가 오면 "작업 도중 포토샵을 조작하면 프로그램이 멈춘다"는 안내를 띄우고 임시 파일을 정리한 뒤 버튼을 다시 켜도록 했다. 같은 내용을 화면의 주의사항에도 넣었다. 여러 사람이 쓰는 프로그램으로 바꾸기 처음에는 번역 가격을 번역 시작 버튼을 누를 때마다 DB에서 읽었고, 이미지 최대 높이 2000px은 코드에 박혀 있었다. 높이 제한이나 가격을 바꾸려면 프로그램을 다시 배포해야 했다. 그래서 로그인할 때 price 테이블에서 가격, 최대 높이를 한 번에 읽어 오도록 바꾸고, 높이 초과 시의 추가 포인트 계산식과 주의사항 문구도 그 값을 쓰도록 했다. 이후 PSD/PSB 번역 가격을 따로 두면서 psd_price 컬럼을 추가했는데, 컬럼이 아직 없는 DB에서도 돌아가도록 조회를 단계적으로 시도하게 했다. 컬럼이 없으면 기존 방식으로 읽고, PSD 가격은 일반 가격과 같게 둔다. 가격이 0이면 차감하지 않는다. TXT 추출 버튼 노출도 회원별 컬럼으로 관리해 관리자가 사용자마다 켜고 끌 수 있게 했다. 마지막으로 로그인 전후 화면을 분리하고, 해외 사용자를 위해 UI 문자열 약 80개를 한국어/영어 사전으로 빼서 토글로 바꿀 수 있게 했다. 메시지 박스와 진행 상태 문구까지 모두 t(key) 를 거치도록 바꾸는 작업이 생각보다 손이 많이 갔다. 결과와 회고 이미지 한 장을 넣고 언어를 고르면 OCR부터 PSD 저장까지 자동으로 진행되고, 원본 경로에 원본명_언어코드.psd 가 생긴다. 사용자는 레이어를 열어 어색한 부분만 고치면 된다. 첫 도구에서 사람이 하던 영역 지정, 배경 칠하기, 결과 재작업이 모두 프로그램 쪽으로 넘어왔다. 돌아보면 3,700줄이 넘는 코드를 한 파일에 둔 것은 아쉽다. UI, DB, 외부 API, Photoshop 자동화가 전역 변수로 얽혀 있어서 COM 초기화나 가격 조회 같은 작은 수정도 여러 곳을 같이 고쳐야 했다. 다시 만든다면 OCR·번역·원문 제거·PSD 생성을 각각 입력과 출력이 분명한 모듈로 나누고, UI는 진행 상황만 받아 그리게 하겠다. 그러면 Photoshop 없이도 앞 단계들을 따로 테스트할 수 있었을 것이다. 기간: 2025.10 ~ 2025.12 기술: Python, Tkinter, Google Cloud Vision, OpenAI GPT-4o, Google Gemini, OpenCV, Photoshop COM(pywin32), MySQL, DeepL(초기 버전) 관련 프로젝트: 이미지 파일 자동 번역 프로그램
프로젝트 목록
공개된 기록과 소식
프로필과 소개