반응형
안녕하세요?
일상의 코딩, 일코입니다.
예전 포스팅 중에, 이미지 사이즈 일괄변경 관련하는 방법을 올린 적이 있었습니다.
2021.01.07 - [업무자동화/파이썬-아래아한글 자동화 기초] - HWP여백조정 후 이미지 너비/높이를 폭에 맞게 일괄조정하는 방법
이 글을 쓸 때만 해도
"굉장히 공들여 만든 포스팅"이라고 생각했는데,
댓글알림이 달려서 오랜만에 읽어보니까
'내가 욕심이 어마어마했구나!' 하는 생각이 강하게 드네요.
이것저것 아는 것 전부 다 코드에 우겨넣다 보니까
가독성도 빵이고,
내용도 너무 복잡해져서ㅜㅜ 다시 읽기도 힘드네요.
다섯 조각 이상 쪼개서 시리즈로 다시 연재해도 되겠다 싶네요.
그럼에도, 삽입이미지 사이즈 관련 자동화 작업 하실 때
참고해볼 만한 자료라고는 생각합니다.
리팩토링도 귀찮은데
하물며 리포스팅은...
정말정말 미루고 싶네요.
하여튼,
이 포스팅에는 작은 버그가 있어요.
바로, 이미지 사이즈를 조정하면, 캡션이 사라지는 현상이 있습니다ㅜ
왜 그런지 이유를 추정해보자면,
파라미터셋 테이블의 ShapeObject와 관련 파라미터셋을 찾아 읽어봤는데
"캡션 문자열"은 파라미터셋 안에 아예 포함되어 있지 않더라고요..
그래서인지, GetDefault를 실행해도 현재 캡션의 정보가 파이썬으로 안 넘어오는 것 같아요..
해법은?
복붙을 사용하면 간단히 해결할 수 있습니다.
(가급적 복붙을 자동화에 안 쓰고 싶은데, 이렇게 어쩔 수 없는 경우들이 있네요;)
본 포스팅을 따라해 보고 싶으신 분은
아래 HWP 문서를 다운받아서 따라해봅시다.
전체 작업을 요약하면
0. 문서 여백정보 추출
1. 캡션 복사
①이미지의 캡션 칸에 들어가서(Ctrl-N-C)
②전체선택(Ctrl-A), 복사(Ctrl-C) 후
③캡션영역 밖으로 나감(Shift-Esc)
2. 여백에 맞게 이미지 사이즈 조정(캡션 사라짐)
3. 캡션 다시 붙여넣기
①이미지의 캡션 칸에 들어가서(Ctrl-N-C)
②전체선택(Ctrl-A), 붙여넣기(Ctrl-V) 후
③캡션영역 밖으로 나감(Shift-Esc)
4. 위의 1~3 코드를 반복
위의 1번과 3번 과정은
아래처럼 매크로를 녹화해서
파이썬 함수로 만들어보았습니다.
1. 복사하는 과정 매크로 녹화
녹화한 코드
function OnScriptMacro_중국어1성()
{
HAction.Run("ShapeObjCaption");
HAction.Run("SelectAll");
HAction.Run("Copy");
HAction.Run("CloseEx");
}
파이썬 코드
def 캡션복사():
hwp.HAction.Run("ShapeObjCaption")
hwp.HAction.Run("SelectAll")
hwp.HAction.Run("Copy")
hwp.HAction.Run("CloseEx")
2. 붙여넣는 과정 매크로 녹화
녹화한 코드
function OnScriptMacro_중국어1성()
{
HAction.Run("ShapeObjCaption");
HAction.GetDefault("Paste", HParameterSet.HSelectionOpt.HSet);
with (HParameterSet.HSelectionOpt)
{
}
HAction.Execute("Paste", HParameterSet.HSelectionOpt.HSet);
HAction.Run("CloseEx");
}
파이썬으로 변환한 코드
def 캡션붙여넣기():
hwp.HAction.Run("ShapeObjCaption")
hwp.HAction.Run("SelectAll")
hwp.HAction.Run("Paste")
hwp.HAction.Run("CloseEx")
3. 두 개의 함수를 코드에 추가
전체 코드가 아래와 같이 완성되었습니다.
from tkinter import Tk # GUI로 파일 선택하기 위한 모듈
from tkinter.filedialog import askopenfilename # 파일선택창
import win32com.client as win32 # 한/글 열기 위한 모듈
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(*위치) # 해당 위치로 커서(캐럿) 이동
def 캡션복사():
hwp.HAction.Run("ShapeObjCaption")
hwp.HAction.Run("SelectAll")
hwp.HAction.Run("Copy")
hwp.HAction.Run("CloseEx")
def 사이즈조정():
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(파라미터셋) # 입력한 값 적용
def 캡션붙여넣기():
hwp.HAction.Run("ShapeObjCaption")
hwp.HAction.Run("SelectAll")
hwp.HAction.Run("Paste")
hwp.HAction.Run("CloseEx")
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) # 위에서 정의한 이동함수
캡션복사()
사이즈조정()
캡션붙여넣기()
else: # 컨트롤아이디가 그리기객체가 아니면
pass # 그냥 넘어가기
ctrl = ctrl.Next # 다음 컨트롤로 이동
구현기능에 비해
코드가 굉장히 복잡하고 장황해 보이는데.....
이게 다 제 내공 탓입니다.
부끄럽습니다ㅜ
실행화면은 아래와 같습니다.
의도한 대로 잘 실행되는 것 같네요.
더 깔끔한 구현방법이 있지 않을까 하는 작은 아쉬움이
정말 좁쌀만큼은 있지만,
이쯤에서 욕심을 버리려고 합니다.
이번 포스팅은 여기서 마치겠습니다.
행복한 하루 되세요^^
반응형
'아래아한글 자동화 > python+hwp 중급' 카테고리의 다른 글
선택한 특정 구간만 새로운 파일로 저장하는 함수 만들기 (0) | 2022.03.13 |
---|---|
GetText의 첫 단락 인덱스를 수정해야 하는 이유(최종) (0) | 2022.02.08 |
GetText 실행 후에 찾아가서 수정하는 방법 (2) | 2022.02.06 |
댓글