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

문서 내 모든 이미지를 추출하는 프로그램 feat. 한글메시지박스

by 일코 2022. 4. 14.

지난 포스팅에서..

한글 메시지박스 기능을 활용하면

준수한 (그리고 어색하지 않은) GUI를 구현해주었습니다.

tkinter나 PySide 같은 모듈을 사용하지 않고도요.

2022.04.09 - [업무자동화/파이썬-아래아한글 자동화 기초] - hwp파일 열 때 한/글 자체 다이얼로그를 이용하면 qt도 tkinter도 필요없다!?

 

hwp파일 열 때 한/글 자체 다이얼로그를 이용하면 qt도 tkinter도 필요없다!?

안녕하세요? 한/글에서 제공하는 API 중에는 대화상자를 열어주거나, 파일을 열거나, 대화상자를 띄워주는 메서드가 있습니다. 어쩔 수 없이 PyQt나 tkinter 등을 사용해야 하는 경우도 있지만 (여러

martinii.fun

 

아래의 예제는

한/글 자체 다이얼로그를 적극적으로 활용한 프로그램입니다.

한/글 파일 안에 있는 이미지를 추출해주는 파이썬 프로그램입니다.

언제든 "취소" 누르면 "작업을 취소합니다" 팝업 보여주고 프로그램 종료

 

파일을 고르면 이미지 추출 후에 "ㅇㅇ개의 이미지 추출 완료" 팝업 보여줌

 

간편한 다이얼로그창을 구현하고 싶을 때는

이처럼 한/글 자체 메시지박스 기능만 활용해도 충분한 것 같습니다.

특히 선택한 메뉴에 따라 Result가 리턴하는 값이 바뀌고,

그에 따라 파이썬에서 로직을 짤 수 있다는 점도 참 좋습니다.

컴파일된 프로그램과 소스코드는 여기서 다운받으실 수 있습니다.

한글_이미지추출기.zip
10.65MB

※ 추출한 이미지들은 하위폴더(파일명과 동일) 생성 후 그 안에 저장됩니다.

 

소스코드 전체 공개

메시지박스를 정의한 함수는 26행의 "한글_팝업" 함수입니다.

맥락만 읽어보셔도 이해하시는 데 충분할 것 같습니다.

import os
import sys

import win32com.client as win32


def 한글파일열기():
    global 한글
    한글 = win32.gencache.EnsureDispatch("hwpframe.hwpobject")
    # 한글.XHwpWindows.Item(0).Visible = True
    한글.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule")
    result = 한글_팝업("이미지를 추출할 한/글 파일을 선택해주세요.", 1)
    if result == 2:
        취소종료()
    한글.Run("FileOpen")  # 파일선택 팝업창을 열어서 추출할 한/글파일을 선택합니다.
    return 한글


def 그림추출(경로, 확장자):
    한글.HAction.GetDefault("PictureSave", 한글.HParameterSet.HShapeObjSaveAsPicture.HSet)
    한글.HParameterSet.HShapeObjSaveAsPicture.Path = 경로
    한글.HParameterSet.HShapeObjSaveAsPicture.Ext = 확장자
    한글.HAction.Execute("PictureSave", 한글.HParameterSet.HShapeObjSaveAsPicture.HSet)


def 한글_팝업(문자열, flag):
    메시지박스 = 한글.XHwpMessageBox
    메시지박스.string = 문자열
    메시지박스.Flag = flag
    메시지박스.DoModal()
    return 메시지박스.Result


def 개체로_이동하기(ctrl):
    위치세트 = ctrl.GetAnchorPos(0)
    위치 = (위치세트.Item("List"), 위치세트.Item("Para"), 위치세트.Item("Pos"))
    한글.SetPos(*위치)


def 취소종료():
    한글_팝업(" " * 22 + "작업을 취소합니다.", 0)
    한글.Quit()
    sys.exit(2)


def 하위폴더생성():
    if not 한글.Path:
        취소종료()
    os.chdir(os.path.dirname(한글.Path))
    target_dir = f'이미지#{os.path.basename(한글.Path).rsplit(".")[0]}'
    try:
        os.mkdir(target_dir)
    except FileExistsError as e:
        print(e)
    os.chdir(target_dir)


def 이미지추출():
    이미지번호 = 1
    개체 = 한글.HeadCtrl
    while 개체:
        if 개체.CtrlID == "gso":  # 이미지면?
            개체로_이동하기(개체)
            한글.FindCtrl()
            한글.Run("PictureToOriginal")  # 원래 크기로
            그림추출(os.path.join(os.getcwd(), f"img{이미지번호:03}.jpg"), "jpg")
            print(이미지번호)
            이미지번호 += 1
        else:
            pass
        개체 = 개체.Next
    한글_팝업(f"{이미지번호}개의 이미지 추출작업을 완료하였습니다.", 0)


def 한글종료():
    한글.Clear(1)
    한글.Quit()


if __name__ == '__main__':
    한글파일열기()
    하위폴더생성()
    이미지추출()
    한글종료()

 

메시지박스 부분 코드만 간단히 부연설명드리면,

메시지박스.string은 메시지박스 문자열,

메시지박스.Result는 버튼을 통해 리턴받은 값입니다.

메시지박스.Flag은 메시지박스의 유형입니다.

한/글에서 제공하는 Flag 유형은 아래와 같이 총 7가지입니다.

 

 

Flag : 0

 

Flag : 1

 

Flag : 2

 

Flag : 3

 

Flag : 4

 

Flag : 5

 

Flag : 6

 

그리고,

누르는 버튼에 따라 메시지박스.Result 값이 달라집니다.

대표적으로 1번플래그(확인/취소)의 경우에는

확인버튼을 누른 후에 Result 값은 1, 취소버튼을 눌렀을 경우는 2입니다.

이를 통해 버튼을 통한 분기로직을 짤 수도 있죠.

 

제 소스코드에서는 13행의 if문에서 Result값을 활용했습니다.

혹시 소스코드 중 궁금한 부분이 있으면 댓글로 질문 남겨주시기 바랍니다.

 

그럼, 이번 포스팅은 여기서 마칩니다.

감사합니다.

행복한 하루 되세요!

 

이 이미지 추출 프로그램은
메시지박스 예제로만 활용되기에는 아까울 정도로 제법 괜찮은 프로그램입니다.
본문이나 표 안에 있는 모든 이미지를 품질손실이나 용량뻥튀기 없이 잘 추출해주거든요.
물론 삽입당시의 파일명을 복원해주지는 못하는 등 아쉬운 부분이 있기는 하고요.
hwpx포맷의 등장 덕분에 이미지 추출이 엄청나게 간편한 작업이 되어버려서
이렇게 포스팅 예제로만 쓰이는 게 아쉬운 마음에 사족을 달아보았습니다..ㅜ

댓글