PAPAGO의 사진번역 서비스를 가끔 사용했었는데 성능이 굉장히 뛰어나, 대량의 자료를 처리해줄 수 있도록 API 서비스를 내가 만드는 프로그램에 연동하면 좋겠다는 생각을 했었다.
열심히 찾아본 결과 API가 있었다! 링크
가입한지 시간이 조금 되어 과정이 잘 기억은 나지 않으나 아마 저 링크의 설명을 따라가면 쉽게 가입할 수 있을것이다.
가입을 하고나면 위처럼 API를 사용하는데 필요한 client KEY와 client secret 코드를 받을 수 있게된다. 확인링크 (사용가이드를 따라가면 확인할 수 있을 것이다.)
성능은 뛰어났다. 하지만... 대표계정의 무료한도를 잘못알고 있었던 나는 것저것 마구 테스트를 해보았고... 꽤 많은 요금이 청구되었다.
다행히도 무료 credit + 네이버측의 자비로 생활비가 날아가는 일은 일어나지 않았다. 네이버 측에게 진심으로 감사하는 바이다.
여러 확장자의 이미지 가져오기
names = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".tif", ".webp"]
TITLE = "폴더의 제목" # 번역할 이미지가 들어있는 폴더의 제목을 넣어준다.
API_KEY_ID = "Client ID를 넣어준다"
API_KEY = "Client Secret을 넣어준다"
import os
def createFolder(directory, ROOTPATH = ''):
'''
directory = 폴더명, ROOTPATH = 절대경로를 지정할 때 사용하면 좋습니다.
생성된 폴더의 절대(존재한다면)경로를 directory명 + _PATH 변수로 반환합니다.
'''
try:
if not os.path.exists(directory):
os.makedirs(ROOTPATH + directory)
globals()["{}_PATH".format(directory)] = ROOTPATH + directory
except OSError:
print (directory, "폴더를 생성할 수 없습니다.")
import glob
import natsort
# folder_path = "이미지 폴더의 경로" ## 절대경로로 이미지를 찾을 사람을 위한 코드
output = []
for i in names:
output += glob.glob(f'{folder_path}\\{TITLE}\\*{i}')
after_order_list = natsort.natsorted(output)
print(after_order_list)
print(len(after_order_list))
webp파일을 png파일로 변경
webp 파일은 번역을 못한다.
jpg, png 파일을 번역한다면 건너뛰어도 무방하다.
# webp을 png로 변경
from PIL import Image
import os
from tqdm import tqdm
if len(output) >= 1:
for i in tqdm(after_order_list):
im = Image.open(i).convert("RGB")
im.save(i[:-4] + "png", "png")
[os.remove(f) for f in glob.glob(f'{folder_path}\\{TITLE}\\*.webp')]
after_order_list = glob.glob(f'{folder_path}\\{TITLE}\\*png')
print(after_order_list)
해상도 변경
가로 또는 세로가 1960을 넘는 이미지는 번역을 못한다.
이미지의 가장 긴 부분을 비율을 유지하며 1960px 이하로 줄이는 코드이다.
# 해상도 변경
import shutil
shutil.copytree(f"{folder_path}" + str(TITLE), f"{folder_path}" + str(TITLE) + "temp")
from PIL import Image
from tqdm import tqdm
after_order_list = glob.glob(f'{folder_path}\\{TITLE}temp\\*png')
for i in tqdm(after_order_list):
img = Image.open(i)
if (img.width > 1960) & (img.width > img.height):
img_resize = img.resize((int(1960), int(img.height * 1960 / img.width)))
elif (img.height > 1960) & (img.width < img.height):
img_resize = img.resize((int(img.width * 1960 / img.height), int(1960)))
elif (img.width > 1960) & (img.width == img.height):
img_resize = img.resize((int(1960), int(1960)))
else:
img_resize = img.resize((int(img.width), int(img.height)))
img_resize.save(i)
번역
언어 | code |
---|---|
한국어 | ko |
영어 | en |
일본어 | ja |
중국어 간체 | zh-CN |
중국어 번체 | zh-TW |
베트남어 | vi |
태국어 | th |
인도네시아어 | id |
프랑스어 | fr |
스페인어 | es |
러시아어 | ru |
독일어 | de |
이탈리아어 | it |
import requests
from requests_toolbelt import MultipartEncoder
import uuid
import json
import base64
from tqdm import tqdm
import shutil
data_list = []
createFolder(TITLE + "translated", ROOTPATH = f"{folder_path}")
count = 0
temp = after_order_list
except_count = 0
# for n in tqdm(temp):
data = {
'source': 'auto',
'target': 'ko',
'image': (n, open(n, 'rb'), 'application/octet-stream', {'Content-Transfer-Encoding': 'binary'})
}
m = MultipartEncoder(data, boundary=uuid.uuid4())
headers = {
"Content-Type": m.content_type,
"X-NCP-APIGW-API-KEY-ID": API_KEY_ID,
"X-NCP-APIGW-API-KEY": API_KEY
}
try:
url = "https://naveropenapi.apigw.ntruss.com/image-to-image/v1/translate"
res = requests.post(url, headers=headers, data=m.to_string())
# print(res.text)
# renderedImage -> 이미지 파일로 출력
resObj = json.loads(res.text)
imageStr = resObj.get("data").get("renderedImage")
imgdata = base64.b64decode(imageStr)
data_list.append(data)
if count < 10:
filename = f'{folder_path}\\{TITLE}translated\\000{count}.png'
count += 1
with open(filename, 'wb') as f:
f.write(imgdata)
elif count < 100:
filename = f'{folder_path}\\{TITLE}translated\\00{count}.png'
count += 1
with open(filename, 'wb') as f:
f.write(imgdata)
elif count < 1000:
filename = f'{folder_path}\\{TITLE}translated\\0{count}.png'
count += 1
with open(filename, 'wb') as f:
f.write(imgdata)
else:
filename = f'{folder_path}\\{TITLE}translated\\{count}.png'
count += 1
with open(filename, 'wb') as f:
f.write(imgdata)
except:
except_count += 1
if count < 10:
destination = f'{folder_path}\\{TITLE}translated\\000{count}.png'
shutil.copyfile(n, destination)
elif count < 100:
destination = f'{folder_path}\\{TITLE}translated\\00{count}.png'
shutil.copyfile(n, destination)
elif count < 1000:
destination = f'{folder_path}\\{TITLE}translated\\0{count}.png'
shutil.copyfile(n, destination)
else:
destination = f'{folder_path}\\{TITLE}translated\\{count}.png'
shutil.copyfile(n, destination)
count += 1
print(len(temp), except_count)
if os.path.exists(f"{folder_path}" + str(TITLE) + "temp"):
shutil.rmtree(f"{folder_path}" + str(TITLE) + "temp")
요금 폭탄에 대한 두려움을 언급했지만 무료 범위 내에서만 사용한다면 안전하니 서비스 프로토타입을 만들거나 소량의 이미지를 번역하는데에는 유용하게 사용할 수 있을 것이라 생각한다.
혹시라도 코드에 오류가 발생한다면 경로문제일 확률이 높다. 상대경로로 사용하던 코드를 절대경로로 바꿔 아마 {folder_path}로 변경되지 않은 부분이 있을 수 있다.
혹시라도 그런 부분이 있다면 알려주시면 감사하겠습니다.