관리 메뉴

솜씨좋은장씨

[Python] Python을 활용하여 대량의 한글 파일(hwp) 썸네일 편하게 만들어보기! 본문

Programming/Python

[Python] Python을 활용하여 대량의 한글 파일(hwp) 썸네일 편하게 만들어보기!

솜씨좋은장씨 2020. 11. 4. 21:38
728x90
반응형

최근 약 3만개의 한글파일을 첫페이지를 이미지로 500x707크기의 썸네일을 만들어야하는 일이 있었습니다.

30개의 파일이었으면 귀찮더라도 그냥 모든 파일을 하나하나 열어서 첫 페이지를 이미지로 저장하게끔 하였겠지만

3만개의 파일을 하나하나 열어서 하기에는 너무 많은 양이 었습니다.

 

저는 이를 파이썬으로 코드를 작성하여 한번에! 촤르륵 실행해보기로 하였습니다.

 

파이썬을 배우고 나서부터는 이런 대량의 파일을 다루는 작업이나 

단순 반복 작업, 수많은 파일 속에서 하나의 파일 찾기와 같은 작업을 주로 파이썬을 활용하여 진행하게 되는 것 같습니다.

 

진행한 환경

Windows 10 + 한글 2018 + Python3,7 ( pywin32 라이브러리 ) 에서 진행하였습니다.

 

이 작업을 진행하기 위해서는 무조건!

한글이 설치되어있어야 합니다.

---------------------------------------------------------------------------
com_error                                 Traceback (most recent call last)
~\anaconda3\lib\site-packages\win32com\client\dynamic.py in _GetGoodDispatch(IDispatch, clsctx)
     88                 try:
---> 89                         IDispatch = pythoncom.connect(IDispatch)
     90                 except pythoncom.ole_error:

com_error: (-2147221005, '잘못된 클래스 문자열입니다.', None, None)

During handling of the above exception, another exception occurred:

com_error                                 Traceback (most recent call last)
<ipython-input-1-11b4022efcb1> in <module>
      7 print(os.listdir())
      8 
----> 9 hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")
     10 hwnd = win32gui.FindWindow(None, 'Noname 1 - HWP')
     11 

~\anaconda3\lib\site-packages\win32com\client\gencache.py in EnsureDispatch(prog_id, bForDemand)
    525 def EnsureDispatch(prog_id, bForDemand = 1): # New fn, so we default the new demand feature to on!
    526         """Given a COM prog_id, return an object that is using makepy support, building if necessary"""
--> 527         disp = win32com.client.Dispatch(prog_id)
    528         if not disp.__dict__.get("CLSID"): # Eeek - no makepy support - try and build it.
    529                 try:

~\anaconda3\lib\site-packages\win32com\client\__init__.py in Dispatch(dispatch, userName, resultCLSID, typeinfo, UnicodeToString, clsctx)
     93   """
     94   assert UnicodeToString is None, "this is deprecated and will go away"
---> 95   dispatch, userName = dynamic._GetGoodDispatchAndUserName(dispatch,userName,clsctx)
     96   return __WrapDispatch(dispatch, userName, resultCLSID, typeinfo, clsctx=clsctx)
     97 

~\anaconda3\lib\site-packages\win32com\client\dynamic.py in _GetGoodDispatchAndUserName(IDispatch, userName, clsctx)
    112         else:
    113                 userName = str(userName)
--> 114         return (_GetGoodDispatch(IDispatch, clsctx), userName)
    115 
    116 def _GetDescInvokeType(entry, invoke_type):

~\anaconda3\lib\site-packages\win32com\client\dynamic.py in _GetGoodDispatch(IDispatch, clsctx)
     89                         IDispatch = pythoncom.connect(IDispatch)
     90                 except pythoncom.ole_error:
---> 91                         IDispatch = pythoncom.CoCreateInstance(IDispatch, None, clsctx, pythoncom.IID_IDispatch)
     92         else:
     93                 # may already be a wrapped class.

com_error: (-2147221005, '잘못된 클래스 문자열입니다.', None, None)

한글이 설치되어있지 않다면 위와 같은 오류 메세지가 나오면서 제대로 실행이 되지 않습니다.

 

한글이 설치되어있지 않다면!!! 반드시 설치를 하고 진행하기 바랍니다.

 

필요 라이브러리 설치

다음으로는 pywin32를 설치합니다.

 

Python for Windows Extensions - Browse /pywin32/Build 221 at SourceForge.net

×

sourceforge.net

먼저 위의 링크로 이동합니다.

이동한 후에 내 개발환경의 Python 버전과 Windows Bit에 맞는 파일을 선택합니다.

 

저는 Windows 10 64Bit 와 Python의 버전이 3.7이므로 pywin32-221.win-amd64-py.3.7.exe를 다운로드 받았습니다.

다운로드는 내 개발환경에 맞는 파일을 클릭하면 약 5초 이후 자동으로 다운로드가 시작됩니다.

 

내 Windows가 몇 Bit 인지 확인하는 방법은 아래의 링크를 참고 바랍니다.

 

[Windows 10] 내 컴퓨터가 32bit인지 64bit인지 확인하는 방법

1. 먼저 새 탐색기 창을 하나 열어서 내 PC로 이동합니다. 2. 왼쪽 배너 내 PC 아이콘 또는 빈 공간에 오른쪽 마우스를 클릭하고 속성을 눌러 줍니다. 3. 시스템 항목 안에있는 시스템 종류를 확인합

somjang.tistory.com

 

Python 버전을 확인하는 방법은 터미널에서

> python3 -V
> python -V

명령어를 통해 확인하면 됩니다.

 

내 개발환경에 맞는 파일을 다운로드 받았다면! 설치를 진행합니다.

갑자기 파란색 화면이 나오면 당황스러울 수 있지만 침착하고 다음을 클릭하여 설치를 진행합니다.

 

설치를 완료하였다면! 코드를 작성하기 전에 진행해야할 과정이 아직 하나 더 남아있습니다.

 

바로 한글2018에 보안모듈을 등록하는 과정입니다.

 

해당 과정은 아래의 링크를 참고 바랍니다.

 

위의 영상을 보고 보안승인모듈 설치를 완료하였다면 이제 코드를 작성합니다.

 

코드 작성

HwpAutomation의 CreatePageImage를 활용합니다.

각 파라미터는 위의 사진을 참고 바랍니다.

import os
import win32com.client as win32
import win32gui

BASE_DIR = "C:\\PythonHome\\hwp\\data\\"
os.chdir(BASE_DIR)

hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")
hwnd = win32gui.FindWindow(None, 'Noname 1 - HWP')
hwp.RegisterModule("FilePathCheckDLL", "SercurityModule")

print(hwnd)

win32gui.ShowWindow(hwnd, 0)

file_list = [file for file in os.listdir() if file != "result"]
print(file_list)


for i in file_list:
    hwp.Open(os.path.join(BASE_DIR, i))
    true_false = hwp.CreatePageImage(BASE_DIR + "\\" + "{}".format(i.replace(".hwp", "")), 0, resolution=300)
    
    if true_false == True:
        print("Success")
    else:
        print("Fail")

hwp.Quit()

먼저 위의 코드를 실행하게 되면 "bmp" 형식의 이미지 파일로 저장이 됩니다.

 

이 bmp 이미지를 500 x 707 사이즈로 리사이징하고 jpg로 저장하여 활용하는 코드는 아래와 같습니다.

from PIL import Image

file_list = os.listdir("./")
img_list = [file for file in file_list if ".bmp" in file]
print(img_list)

BASE_DIR = "C:\\PythonHome\\42maru_hwp\\data\\"

for i, img_file in enumerate(img_list):
    img = Image.open(BASE_DIR + "\\" + img_file).convert("RGB")
    new_img = img.resize((500, 707), Image.ANTIALIAS)
    new_img.save(BASE_DIR + "\\" + "{}.jpg".format(img_file.replace(".bmp", "")), format='jpeg', quality=100)

리사이징하고 저장하면 화질이 깨지는 이슈가 있었는데 Image.ANTIALIAS 항목을 통해서 깨지지 않게 저장할 수 있습니다.

 

[Python] PIL(Pillow) 라이브러리를 활용하여 이미지 resize 시 깨지지 않게 저장하는 방법!

한글 파일에서 첫 페이지만 bmp로 저장한 다음 bmp 파일을 작은 해상도로 resizing 한 후 jpeg로 저장하는 과정에서 이미지가 깨져서 보이는 현상이 있었습니다. 처음에는 한글 API 가 제대로 동작하지

somjang.tistory.com

 

최신 버전의 문서는 아래와 같이 작성되어있었습니다.

여기서는 PIL을 활용하지 않아도 jpg로 저장이 가능한 것으로 나와있습니다.

하지만 저는 시도하였을때 해당 방법이 되지 않아 위의 방법을 활용했었습니다.

혹시라도 궁금하신 분들은 아래의 방법도 시도해보시고 된다면 더 편하게 시도해볼 수 있을 것 같습니다.

읽어주셔서 감사합니다.

Comments