본문 바로가기
아래아한글 자동화/python+hwp 중급

[8/8] 여러 한/글 문서에서 이미지 추출(최종)

by 일코 2022. 10. 25.

메인함수

if __name__ == '__main__':
    hwp = 한글프로그램_실행()
    취합폴더 = Path(r"C:\Users\smj02\Desktop\취합문서")
    한글문서리스트 = 취합폴더.glob("*.hwp")
    for 한글문서 in 한글문서리스트:
        문서열기(한글문서)
        제목리스트, 제목함수 = 제목뽑기()
        제목폴더_만들기(제목리스트)
        이미지저장(제목함수)
        현재문서닫기()
    한글프로그램_종료()

이 메인함수는 이 튜토리얼 시작 때 미리 보여드렸습니다.

여기까지 오는 동안 필요한 모든 함수를 하나씩 정의해봤으니,

이제는 위 메인함수의 프로세스를 어느 정도 파악을 하셨을 거라고 생각합니다.

 

그럼 앞에서 정의한 함수들을 포함한 전체 소스코드를 보여드리고

실행결과를 보여드리겠습니다.

전체 소스코드

from pathlib import Path
import win32com.client as win32


def 한글프로그램_실행(visible=True):
    hwp = win32.gencache.EnsureDispatch("hwpframe.hwpobject")
    hwp.XHwpWindows.Item(0).Visible = visible
    hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule")
    return hwp


def 문서열기(한글파일):
    hwp.Open(한글파일)


def 현재문서닫기():
    hwp.Clear(option=1)  # 변경내용 버리고 문서 닫기


def 한글프로그램_종료():
    hwp.Quit()


def 그림추출(경로):
    hwp.HAction.GetDefault("ShapeObjSaveAsPicture", hwp.HParameterSet.HShapeObjSaveAsPicture.HSet)
    hwp.HParameterSet.HShapeObjSaveAsPicture.Path = 경로.as_posix()
    hwp.HParameterSet.HShapeObjSaveAsPicture.Ext = 경로.suffix[1:].upper()  # "JPG"
    hwp.HAction.Execute("ShapeObjSaveAsPicture", hwp.HParameterSet.HShapeObjSaveAsPicture.HSet)


def ctrl로_이동하기(ctrl):
    loc_set = ctrl.GetAnchorPos(0)
    hwp.SetPosBySet(loc_set)


def 제목뽑기():
    """
    빈 네모(□) 글머리기호로 시작하는 제목의
    텍스트와 문단번호를 추출한 후에
    이를 통해 해당 구간의 제목을 리턴하는 함수를 만들고
    그 함수를 리턴함

    <예시>
    title_list = ['나무사진', '꽃사진', '풀사진']
    range_list = [2, 5, 8]
    title_dict = {range(2, 5): '나무사진', range(5, 8): '꽃사진', 8: '풀사진'}

    title_func(4) => "나무사진"
    title_func(5) => "꽃사진"
    title_func(9) => "풀사진"
    """
    hwp.InitScan(option=0, Range=0x77)  # 0:본문을 대상으로, 0x77:문서의 시작부터 문서의 끝까지
    state = 0  # state 변수 초기화
    title_list = []  # 제목 담을 리스트
    range_list = []  # 문단시작점 담을 리스트
    while state != 1:  # 문서 끝에 도달하기 전까지 반복해서
        state, text = hwp.GetText()  # 한 줄바꿈씩 탐색함
        if text.startswith("□ "):  # 탐색결과가 "□ "으로 시작하면
            title_list.append(text[1:].strip())  # 글머리 빼고 title_list에 추가한 후
            hwp.MovePos(201)  # 해당 위치로 이동해서
            range_list.append(hwp.GetPos()[1])  # 문단번호 추출해서 range_list에 추가
    hwp.ReleaseScan()  # 탐색 종료
    title_dict = {}  #
    for idx, title in enumerate(title_list):
        try:
            title_dict[range(range_list[idx], range_list[idx+1])] = title
        except IndexError:
            title_dict[range_list[idx]] = title

    def title_func(num):
        for i in title_dict.keys():
            if num < list(title_dict.keys())[-1]:
                if num in i:
                    return title_dict[i]
            else:
                return title_dict[list(title_dict.keys())[-1]]

    return title_list, title_func


def 제목폴더_만들기(title_list):
    for title in title_list:
        Path.mkdir(취합폴더/"취합사진"/title, parents=True, exist_ok=True)


def 이미지저장(제목함수):
    ctrl = hwp.HeadCtrl
    이미지번호 = 1
    이전제목 = ""
    while ctrl != None:
        if ctrl.CtrlID == "gso":
            ctrl로_이동하기(ctrl)
            hwp.Run("CloseEx")  # 표 안에 있는 경우, 표 밖으로 나옴
            제목 = 제목함수(hwp.GetPos()[1])
            if 이전제목 != 제목:
                이미지번호 = 1
            이전제목 = 제목
            ctrl로_이동하기(ctrl)
            hwp.FindCtrl()
            hwp.HAction.Run("PictureToOriginal")  # 원래 크기로
            문서이름 = hwp.Path.split('\\')[-1][:-4]  # ".hwp" 제거
            저장할_파일경로 = 취합폴더/"취합사진"/제목/f"{문서이름}_{제목}#{이미지번호}.jpg"
            그림추출(저장할_파일경로)
            이미지번호 += 1
        else:
            pass
        ctrl = ctrl.Next


if __name__ == '__main__':
    hwp = 한글프로그램_실행()
    취합폴더 = Path(r"C:\Users\smj02\Desktop\취합문서")
    한글문서리스트 = 취합폴더.glob("*.hwp")
    for 한글문서 in 한글문서리스트:
        문서열기(한글문서)
        제목리스트, 제목함수 = 제목뽑기()
        제목폴더_만들기(제목리스트)
        이미지저장(제목함수)
        현재문서닫기()
    한글프로그램_종료()

 

전체 소스코드 실행결과

"{파일명}_{문단제목}#{번호}.jpg" 서식으로

모든 이미지를 개별 폴더 안에 일괄저장하는 작업을 마쳤습니다.

긴 글 읽어주셔서 감사합니다.

부디 이 튜토리얼이 여러분의 업무자동화에 도움이 되기를 바랍니다.

그럼 이것으로 "제목 이름의 폴더별로 이미지 저장" 튜토리얼을 모두 마칩니다,

 

 

본 튜토리얼 관련한 질문은 댓글로 달아주시면 대댓글이나 추가포스팅으로 설명드리겠습니다.

 

 

댓글