본문 바로가기

파이썬-아래아한글 자동화 기초

HWP여백조정 후 이미지 너비/높이를 폭에 맞게 일괄조정하는 방법

728x90

 

 

HWP포맷을 사용하는 소규모의 출판사가 의외로 많다는 걸 최근들어 알게 되었다.

그도 그럴 것이, 인디자인이나 퍼블리셔 같은 프로그램 없이도

직접 책을 출판하고 SNS로 홍보할 수 있는 시대가 열렸다. 이 부분은 다음에 더 이야기하기로 하고,

 


 

수백 페이지 규모의 HWP문서를 만질 때는, 특히 이미지가 많은 문서라면 정말 고생하는 경우가 있는데,

그 중 최고랄 만한 작업은 바로 "용지를 바꾸거나 여백을 변경했을 때"이다. ㄷㄷㄷㄷ

이러면 표 뿐만 아니라 각각의 이미지 전체를 문서 폭 안으로 우겨넣거나 늘려야 하는데,

(만약 이미지 너비가 "고정값"이 아니면 더 고생한다. 예를 들어 이미지 너비가 "쪽 100%"로 설정되어 있었는데 용지의 좌우여백을 변경해버리면 폭만 자동으로 줄어들어버려서 그림이 좌우로 쪼그라들어버린다.)

작업시간이 문서분량에 비례하는 만큼, 출판작업시 엄청난 노가다 작업이 발생할 수 있는 상황이다.

하지만 몇 가지 스크립트를 익혀두었다면 손쉽게 일괄처리할 수 있다.

모든 코드를 다 외울 필요는 없으며, 외울 수도 없다. 지금 이 상황에 필요한 명령어만 소개해 드리겠다.

(참고로 필자는 파이썬을 애용한다. 한/글 내장스크립트의 한계를 쉽게 넘어설 수 있다.)

우선 자동화작업 순서를 한 번 나열해보겠다.
(단, 문서 내 모든 이미지는 쪽 너비로 "고정값" 삽입된 것으로 가정한다. 이는 문서 끝에 추가설명하겠다.)

 


 

자동화작업 순서

좌우가 너무 좁아 보여서, 좌우여백을 각각 10mm씩 추가했다고 가정한다.

1. 문서 내 모든 이미지를 순차적으로 탐색하면서

2. 이미지 하나씩 선택해서,

3. 이미지의 현재 너비와 높이값을 저장해놓고,

4. 이미지 너비를 쪽에 맞춰 수정한 후,

5. 이미지 높이를 그에 맞게 수정한다.(너비의 변경값/기존값 이용)

 


 

번호별로 필요한 메서드

1. hwp.InitScan

2. hwp.FindCtrl

3. hwp.CreateAction, CreateSet, GetDefault, 

4~5. CreateItemSet, SetItem, MiliToHwpUnit, Execute

이 정도면 충분할 것 같다.

 


 

예제로 첨부한 HWP파일은

용지설정에서 제본여백 15mm를 추가했더니, 그림이 오른쪽으로 15mm 튀어나와버린 상태.

 

간단히 설명드리면, 용지설정에서 제본여백 15mm를 추가했더니, 그림이 오른쪽으로 15mm 튀어나와버린 상태이다.
같이 따라해보고 싶은 분들을 위해 파일도 아래 첨부한다.

 

여백조정후이미지조정.hwp
0.94MB

 


 

결과를 먼저 보여드림.

코딩을 이용해서 이미지의 너비와 높이를 용지에 맞춰 일괄로 줄였다. (클릭)

코딩을 이용해서 이미지의 너비와 높이를 용지에 맞춰 일괄로 줄였다. (동영상)

 


 

코드는 아래와 같다.

 

import win32com.client as win32  # 한/글 열기 위한 모듈
from tkinter import Tk  # GUI로 파일 선택하기 위한 모듈
from tkinter.filedialog import askopenfilename  # 파일선택창


def hwp_init(filename):  # 한/글 여는 코드가 길어서 미리 만들어둠
    hwp = win32.gencache.EnsureDispatch("HWPFrame.HwpObject")  # 한/글 객체 생성
    hwp.RegisterModule("FilePathCheckDLL", "FilePathCheckerModule")  # 보안모듈 실행
    hwp.Open(filename)  # GUI에서 선택한 파일 열기
    hwp.XHwpWindows.Item(0).Visible = True  # 한/글 창 숨김해제(초기에는 백그라운드상태)
    hwp.HAction.Run("FrameFullScreen")  # 전체화면
    return hwp  # hwp객체 리턴


def Hwp유닛을_밀리미터로(HWP유닛):  # MiliToHwpUnit메서드의 반대. 계산 귀찮아서 만들어둠.
    return HWP유닛 / 7200 * 25.4  # 1 inch = 7200 HWPUNIT, 1mm = 283.465 HWPUNIT


def ctrl로_이동하기(ctrl):  # 그리기객체나 표 등 컨트롤 오브젝트로 이동하는 함수
    위치세트 = ctrl.GetAnchorPos(0)  # 현재 선택된 컨트롤의 위치파라미터 추출
    위치 = (위치세트.Item("List"), 위치세트.Item("Para"), 위치세트.Item("Pos"))  # 튜플로 변환
    hwp.SetPos(*위치)  # 해당 위치로 커서(캐럿) 이동


if __name__ == '__main__':  # 메인함수 파트
    root = Tk()  # GUI(그래픽 유저 인터페이스) 인스턴스 생성
    filename = askopenfilename()  # 파일열기창 실행
    root.destroy()  # 파일선택 후 tkinter 종료
    hwp = hwp_init(filename=filename)  # 위에서 정의한 한/글 열기 함수
    페이지액션 = hwp.CreateAction("PageSetup")  # 페이지셋업 액션 실행준비
    페이지세트 = 페이지액션.CreateSet()  # 페이지 설정을 위한 파라미터 배열(비어있음) 생성
    페이지액션.GetDefault(페이지세트)  # 파라미터에 현재문서의 값을 채워넣음
    종이너비 = Hwp유닛을_밀리미터로(페이지세트.Item("PageDef").Item("PaperWidth"))  # 채워넣은 값 중 종이너비
    좌측여백 = Hwp유닛을_밀리미터로(페이지세트.Item("PageDef").Item("LeftMargin"))  # 채워넣은 값 중 좌측여백
    우측여백 = Hwp유닛을_밀리미터로(페이지세트.Item("PageDef").Item("RightMargin"))  # 채워넣은 값 중 우측여백
    제본여백 = Hwp유닛을_밀리미터로(페이지세트.Item("PageDef").Item("GutterLen"))  # 채워넣은 값 중 제본여백
    제본타입 = Hwp유닛을_밀리미터로(페이지세트.Item("PageDef").Item("GutterType"))  # 0:한쪽, 1:맞쪽, 2: 위쪽

    ctrl = hwp.HeadCtrl  # 문서 중 첫번째 컨트롤 선택
    while ctrl != None:  # 마지막 컨트롤까지 순회할 것.
        if ctrl.CtrlID == "gso":  # 컨트롤아이디가 그리기객체(gso)이면
            ctrl로_이동하기(ctrl)  # 위에서 정의한 이동함수
            hwp.FindCtrl()  # 해당 객체 선택
            이미지액션 = hwp.CreateAction("ShapeObjDialog")  # 이미지수정액선 실행준비
            이미지세트 = 이미지액션.CreateSet()  # 이미지수정을 위한 파라미터 배열(비어있음) 생성
            이미지액션.GetDefault(이미지세트)  # 빈 파라미터 배열에 현재문서의 값을 채워넣음
            기존너비 = Hwp유닛을_밀리미터로(이미지세트.Item("Width"))  # 선택 이미지의 현재너비 저장
            기존높이 = Hwp유닛을_밀리미터로(이미지세트.Item("Height"))  # 선택 이미지의 현재높이 저장
            변경쪽너비 = 종이너비-좌측여백-우측여백-(0 if 제본타입==2 else 제본여백)  # 변경할 쪽너비 계산
            파라미터셋 = 이미지세트.CreateItemSet("ShapeObject", "ShapeObject")  # 이미지 수정을 위한 파라미터셋 생성
            파라미터셋.SetItem("Width", hwp.MiliToHwpUnit(변경쪽너비))  # 이미지너비 변경값 입력
            파라미터셋.SetItem("Height", hwp.MiliToHwpUnit(기존높이*변경쪽너비/기존너비))  # 이미지높이 변경값 입력
            이미지액션.Execute(파라미터셋)  # 입력한 값 적용
        else:  # 컨트롤아이디가 그리기객체가 아니면
            pass  # 그냥 넘어가기
        ctrl = ctrl.Next  # 다음 컨트롤로 이동

# 끝.

 

hwp스크립트의 가장 큰 장점이라면 역시,
타 프로그램 대비 굉장히 디테일하고 강력하게 문서수정을 할 수 있다는 점이 아닐까?
반면 위처럼 간단한 작업임에도 코드가 다소 길어지는 아쉬움이 남는다.
(직접 짜는 방식이 아니라 API매뉴얼이나 스크립트녹화코드에서 복붙하는 방식이라, 의외로 작업은 빠르다.)

라인별로 간단한 주석을 달아놓았지만, 이해하기 쉽지 않은 부분도 있을 것.
일부 메서드나 한/글컨트롤 문법은 다른 포스팅에서 추가로 설명할 예정이지만,
방명록이나 댓글로 문의 남겨주시면 언제든 답변해 드리고자 한다.
다만, 코드나 파일을 가지고 이야기를 나눠야 할 경우 martinii.fun지메일로 보내주시면 된다.

이번 포스팅은 여기서 마친다.
긴 글 읽어주셔서 감사하다.

행복한 하루 되시길!

728x90