본문 바로가기
카테고리 없음

[파이썬-한/글]이미지 삽입시 "글뒤로 보내기" 설정방법

by 일코 2021. 8. 14.

김재석님께서 질문 주신 내용

안녕하세요? 먼저 질문글에서 언급해 주신 글은 이것으로 추정됩니다.

 

[자동화문의] 표 안에 이미지 넣는 작업

[1] 안녕하세요? 코딩하는 회사원들 유튜브 채널 구독자입니다. 궁금한것이 있어 이렇게 메일 드립니다. 저희회사에서는 매월 천개가 넘는 그림파일을 한글파일의 특정서식의 표에 붙여넣는 단

martinii.fun

위 글 중에 "이미지 삽입" 코드는 딱 한 줄입니다.

hwp.InsertPicture(파일, Embedded=True, sizeoption=3)

# sizeoption 파라미터 설명
# 0 : 이미지 원래의 크기로 삽입한다. width와 height를 지정할 필요 없다.
# 1 : width와 height에 지정한 크기로 그림을 삽입한다.
# 2 : 현재 캐럿이 표의 셀 안에 있을 경우, 셀의 크기에 맞게 자동 조절하여 삽입한다.
#     width는 셀의 width만큼, height는 셀의 height만큼 확대/축소된다.
#     캐럿이 셀 안에 있지 않으면 이미지의 원래 크기대로 삽입된다.
# 3 : 현재 캐럿이 표의 셀 안에 있을 경우, 셀의 크기에 맞추어 원본 이미지의 가로 세로의 비율이 동일하게 확대/축소하여 삽입한다.

그런데, InsertPicture 메서드로는 "글자처럼 취급(TreatAsChar)"이라든지, "본문과의 배치(TextWrap)" 같은 속성 변경이 불가능하기 때문에, 컨트롤의 속성을 직접 수정해줘야 합니다.

참고로 API매뉴얼의 C++ 예제(아래)도, 이미지삽입 후 글자처럼취급을 해제하고 글 뒤로 옮기는 작업입니다.

CComPtr<IDispatch> pctrl;
COleVariant oleDefault(0);

pctrl = m_cHwpCtrl.InsertPicture(_T("c:\\windows\\부채.bmp"), COleVariant(TRUE), COleVariant(2), 
					oleDefault, oleDefault, oleDefault, oleDefault, oleDefault); 
if (!pctrl)
{
	AfxMessageBox("그림을 삽입할 수 없습니다.");
}
else
{	//그림 삽입 후에 컨트롤의 속성을 추가적으로 더 변경할 수 있다.
	DHwpParameterSet dset;
	CComPtr<IDispatch> pset;
	DHwpCtrlCode dctrlcode;
	dctrlcode.AttachDispatch(pctrl);
	pset = m_cHwpCtrl.CreateSet(_T("ShapeObject"));
	dset.AttachDispatch(pset);
	dset.SetItem(_T("TreatAsChar"), (COleVariant)(short)FALSE); //글자처럼 취급
	dset.SetItem(_T("TextWrap"), (COleVariant)(short)2);  //본문과의 배치 : 0:어울림, 1:자리차지,
									//2:글 뒤로, 3:글 앞으로
	dctrlcode.SetProperties(pset); //주의 : Ctrl의 속성을 직접 수정했으므로 Undo history에 기록이 되지 않는다.
	dset.DetachDispatch();
	dctrlcode.DetachDispatch();

 

하여튼, 이미지 속성(글자처럼취급, 본문과의배치)을 직접 수정하는 방법을 알아내는 방법은 크게 두 가지로,

 

1. 스크립트매크로 녹화한 코드를 사용하거나, 

 

2. API문서 중 Action Table.hwp와 ParameterSet.hwp 파일을 참고해서 메서드 작성

 

입니다.

 

둘 다 간편한 방법이므로 둘 다 보여드리겠습니다.

비교해보시면서 자신에게 맞는 방법을 쓰시기 바랍니다.

1. "스크립트매크로 녹화"로 코드 알아내기

① 이미지를 삽입합니다. (이 때 글자처럼취급이 적용되어 있어야 합니다.)

이미지 삽입(글자처럼 취급)

② 스크립트녹화 시작(Shift-Alt-H,  아무 슬롯 고르고 "정의(D)" 클릭)

스크립트 녹화 시작

③ Ctrl-N-K를 눌러 "개체 속성"창 열기(이미지 우클릭이 안되므로)

개체속성 창 열기

글자처럼 취급 해제하고, 본문과의 배치를 "글 뒤로" 선택한 후 "설정(D)" 클릭

원하는 설정값 적용

⑤ 녹화종료(Shift-Alt-X) 후 스크립트목록 열어서(Shift-Alt-L) 녹화한 코드 열기(Alt-C)

녹화된 코드

녹화된 코드는 아래와 같아요.

function OnScriptMacro_script5()
{
	FindCtrl();
	HAction.GetDefault("ShapeObjDialog", HParameterSet.HShapeObject.HSet);
	with (HParameterSet.HShapeObject)
	{
		TextWrap = TextWrapType("BehindText");
		TreatAsChar = 0;
		HSet.SetItem("ShapeType", 1);
	}
	HAction.Execute("ShapeObjDialog", HParameterSet.HShapeObject.HSet);
}

⑥ 위 코드를 파이썬 문법에 맞게 수정하고 함수로 정의하면 아래와 같습니다.

(불필요한 라인 및 with문 수정하고 접두어 hwp를 붙임.)

def 이미지_글자처럼취급해제_글뒤로배치():
    hwp.FindCtrl()  # 커서에서 인접한 개체 선택(양쪽에 있으면 우측개체 우선선택)
    hwp.HAction.GetDefault("ShapeObjDialog", hwp.HParameterSet.HShapeObject.HSet)  # 액션 초기화
    hwp.HParameterSet.HShapeObject.TextWrap = hwp.TextWrapType("BehindText")  # 글 뒤로 배치
    hwp.HParameterSet.HShapeObject.TreatAsChar = 0  # 글자처럼 취급 해제
    result = hwp.HAction.Execute("ShapeObjDialog", hwp.HParameterSet.HShapeObject.HSet)  # 실행
    return result  # 실행결과 리턴, 성공시 True를 리턴

※ hwp.FindCtrl() 메서드를 꼭 붙여야 합니다. 위 코드는 개체 선택상태에서만 정상적으로 실행됩니다.

 

⑦ 테스트해봅시다. 잘 되네요.

"글자처럼취급"과 "본문과의배치"가 변경됨

이미지 삽입코드 바로 아래에 "이미지_글자처럼취급해제_글뒤로배치" 함수를 추가하시면 됩니다.

 

2. 또 다른 방법: API매뉴얼에서 메서드 직접찾아 작성

이게 왜 필요할까 싶지만, 간혹 스크립트매크로 녹화시 실행되지 않는 액션들이 있어서 이렇게 직접 API문서를 찾아야만 하는 경우가 있습니다. 근데 해보면 대부분 간단한 편입니다.

 

① Action Table.hwp와 ParameterSet Table.hwp 파일을 엽니다.

"이 파일들까지 열어봐야 하는 작업이라면, 수작업보다 오래 걸릴 수 있으므로 주의..."

② ParameterSet Table.hwp 파일에서 "글자처럼 취급"과 "글 뒤로"를 검색합니다. (둘 다 ShapeObject에 들어있네요.)

"글자처럼 취급"의 아이템아이디는 "TreatAsChar". On/Off일 경우 각각 True/False를 넣으면 됨.
"본문과의 배치" 아이템 아이디는 "TextWrap", "글 뒤로"는 2

이 두 속성이 속해 있던 파라미터셋아이디는 "ShapeObject" 였다는 것도 기억해 두고, 

 

③ Action Table.hwp 에서 파라미터셋아이디가 ShapeObject인 액션 아이디를 찾아봅니다. (상당히 많습니다..)

전부 ShapeObject를 사용하지만 "그림"과는 관계없으므로 패스
이런 것들도 전혀 관계없는 액션이므로 패스.

상당히 많아서 검색에 다소 시간이 걸릴 수 있습니다. 약간 노하우가 필요한 부분입니다.

가장 적절해 보이는 건 역시, ShapeObjDialog(환경설정)으로 보입니다.

 

④그럼 위 정보를 가지고 함수를 짜봅시다. 일반적인 액션생성의 틀은 아래 세 가지 중 하나입니다.

 

첫 번째는 파라미터가 하나도 필요없는 경우의 액션생성 코드입니다.

액션 = hwp.CreateAction(액션아이디)  # 예 : Erase, BreakPara 등
파라미터셋 = 액션.CreateSet()
액션.Execute(파라미터셋)

※ 참고로 위의 코드 세 줄은 hwp.HAction.Run(액션아이디) 또는 hwp.Run(액션아이디) 단축명령어로 실행 가능합니다.

(hwp.HAction.Run은 hwp.Run과 동작의 차이는 없는데, 명령 성공시 True를, 실패시 False를 리턴합니다.)

 

두 번째는 파라미터셋이 필요한 경우의 액션생성 코드입니다.

액션 = hwp.CreateAction(액션아이디)
파라미터셋 = 액션.CreateSet()
액션.GetDefault(파라미터셋)
파라미터셋.SetItem(아이템아이디1, 값)
파라미터셋.SetItem(아이템아이디2, 값)
액션.Execute(파라미터셋)

※ 지금 우리가 작성하려는 코드가 이 경우에 해당합니다.

 

마지막으로 세 번째는 파라미터셋 외에도 서브셋이 필요한 액션생성 코드입니다.

액션 = hwp.CreateAction(액션아이디)
파라미터셋 = 액션.CreateSet()
액션.GetDefault(파라미터셋)
아이템셋 = 파라미터셋.CreateItemSet(아이템아이디, 세트아이디)  # 대부분 세트아이디 == 아이템아이디
파라미터셋.SetItem(아이템아이디1, 값)
파라미터셋.SetItem(아이템아이디2, 값)
아이템셋.SetItem(아이템아이디1, 값)
아이템셋.SetItem(아이템아이디2, 값)
액션.Execute(파라미터셋)

※ 대표적인 사례로 글자속성이나, 용지여백 설정 등이 이에 해당합니다.

(참고 : 4. 문서여백을 파이썬으로 바꿀 수 있을까? (tistory.com))

 

부연설명이 너무 길었네요. 하여튼 위의 두 번째 경우를 참고해서 함수를 완성하면 아래와 같습니다.

def 이미지_글자처럼취급해제_글뒤로배치2():
    액션아이디 = "ShapeObjDialog"
    hwp.FindCtrl()  # 꼭 붙여야 하는데 잊어먹기 쉬움. 개체 선택하는 메서드
    액션 = hwp.CreateAction(액션아이디)
    파라미터셋 = 액션.CreateSet()
    액션.GetDefault(파라미터셋)
    파라미터셋.SetItem("TreatAsChar", False)
    파라미터셋.SetItem("TextWrap", 2)
    액션.Execute(파라미터셋)

※ 재미있는 점은, 파라미터셋 아이디는 입력할 필요가 없다는 것입니다.

 

⑤ 테스트해봅시다. (이 코드 역시 잘 작동하네요.)

액션생성 방법으로 짠 코드. 잘 실행됨.

가급적 포스팅을 짧고 명료하게 쓰고 싶은데 욕심이 붙어서 글이 눈덩이처럼 불어나네요..

도움이 되었으면 좋겠습니다.

 


donaricano-btn

댓글