PAPAGO OCR번역 API코드

P4·2023년 5월 21일
0

Python API

목록 보기
1/1
post-thumbnail

시작하기 전에...

  • 잡설을 건너뛰려면 목차의 코드부터 보시면 됩니다.

PAPAGO의 사진번역 서비스를 가끔 사용했었는데 성능이 굉장히 뛰어나, 대량의 자료를 처리해줄 수 있도록 API 서비스를 내가 만드는 프로그램에 연동하면 좋겠다는 생각을 했었다.

열심히 찾아본 결과 API가 있었다! 링크

가입한지 시간이 조금 되어 과정이 잘 기억은 나지 않으나 아마 저 링크의 설명을 따라가면 쉽게 가입할 수 있을것이다.

가입을 하고나면 위처럼 API를 사용하는데 필요한 client KEY와 client secret 코드를 받을 수 있게된다. 확인링크 (사용가이드를 따라가면 확인할 수 있을 것이다.)


사용후기

  • 성능은 뛰어났다. 하지만... 대표계정의 무료한도를 잘못알고 있었던 나는 것저것 마구 테스트를 해보았고... 꽤 많은 요금이 청구되었다.

  • 다행히도 무료 credit + 네이버측의 자비로 생활비가 날아가는 일은 일어나지 않았다. 네이버 측에게 진심으로 감사하는 바이다.


코드

  • 서비스를 사용하기 전에 반드시 서비스 설명란에서 무료 이용 범위를 정독한 후 사용하기를 권장한다.

  1. 여러 확장자의 이미지 가져오기

    • chatgpt한테 일반적인 이미지 확장자를 알려달라고 해서 적절하지 못한 확장자가 섞여있을 수 있다.
names = [".jpg", ".jpeg", ".png", ".gif", ".bmp", ".tiff", ".tif", ".webp"]
TITLE = "폴더의 제목" # 번역할 이미지가 들어있는 폴더의 제목을 넣어준다.

API_KEY_ID = "Client ID를 넣어준다"
API_KEY = "Client Secret을 넣어준다"

  1. 폴더 생성 함수
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, "폴더를 생성할 수 없습니다.")

  1. 이미지들의 경로 가져오기
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))

  1. 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)

  1. 해상도 변경

    • 가로 또는 세로가 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)

  1. 번역

    • 번역표
언어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}로 변경되지 않은 부분이 있을 수 있다.
    혹시라도 그런 부분이 있다면 알려주시면 감사하겠습니다.

profile
지식을 담습니다.

0개의 댓글