멀미가 심한편이라 VR 기술관련 뉴스는 관심없게 보다가, Leap Motion 개발자 사이트에서 우연히 Oculus 연동 동영상을 보고 관심을 가지게 되었다. 마침 유니터 러닝 센터에서 2시간동안 Oculus 소개와 유니티 연동을 주제로 특별강연이 있어서 참석하게 되었다. 듣고 온 소감을 간단하게 개인적인 입장에서 정리해봤다.


아직 베타 버전 !! 그리고 Oculus 경쟁자가 존재한다.

게임 컨텐츠 개발자로 추정되는 젋은 사람들 보다 게임과 무관해 보이는 연차가 있어보이는 분들이 많이 참석했다. 세미나 시작전 이 점이 신기하게 생각되었는데, 세미나 내용을 듣다 보니 이해가 갔다.

DK 는 Developer Kit 의 약자이고, 현재 제품은 까고 말하자면 아직 베타 버전 이다. 큰 회사(Facebook)에서 막대한 돈을 들여 인수하니 뭔가 있을것 같다는 생각에 탐색차 들린것 이었다. 그래서 그런지 게임 컨텐츠 개발하는 듯한 젊은 분들이 안하는 기초적인 질문들이 반복해서 나오고 있었다. 사이트 한번 들어가서 첫 페이지 조차 읽어 보지도 않은 모양이다.

나도 별 지식 없이 참석했지만, 그렇다고 해서 무지한 상태로 탐색차 들린것도 아닌지라, 자연스레 객관적인 자세가 될 수 밖에 없어서 이런 상황이 재미있게 느껴 졌다.

결과를 찾아서 의미있는 결과물을 남기면서 전진하는 회사는 분명 맞지만, 솔직히 이것이 컨슈머 시장을 장악할지는 잘 모르겠다. 개인적으로는 좀 늦을수 있지만, 마트에 장보러 나간 엄마가 떼쓰는 애들 머리에 씌워줄 수준이 될 때 시작해도 늦지 않을것 같다는 생각이 들었다. 누가 아는가? 애들 머리에 씌워지는게 Oculus 가 아닌 Sony 혹은 Apple 또는 다른 회사의 제품일 수도 있으니 말이다..


Gear VR

강사분이 시연용으로 DK2 Rift 와 Galexy Gear VR 두대를 가져왔다. DK2 Rift 인기가 높아서 Gear VR 을 먼저 보게 되었다. 제품에 대한 정보가 없어서 무선 혹은 유선으로 연결해서 스마트폰의 컨텐츠를 보여주는 구조라고 추측하고 있었다. 프로토콜만 공개 되면 아이폰도 적용이 되겠다 싶었는데.. 기대한것과 달리 핸드폰을 해드기어 앞에 끼우면 핸드폰 화면이 좌우로 나뉘어 DK2 Rift 와 비슷한 경험을 주게 되는 기계적인 구조 였다. 

멀미를 줄이기 위해선 깜빡임이 적어야 하므로 DK2 Rift 는 OLED 기반에 75㎐ 를 사용하고 있는데, Note 4 는 일반적인 수준의 핸드폰용 패널이 들어가서 우려한대로 DK2 Rift 와 비교해서 어른거리는 느낌이 있었다. 레이싱 게임 컨텐츠라도 돌렸으면 바로 멀미를 느겼을것 같았다.

삼성이 페이스북과 손잡고 VR 플렛폼 사업에 뛰어든게 아니라, 단지 Note 4 를 팔기 위한 엑세서리 개발인 것이 티가 났다. 나만 그렇게 생각한게 아니라 참석한 대부분이 같은 예기를 했고, 조금 지나니까 Gear VR 은 강사분 책상에서 놀고 있었다.


새로운 입력도구 Nimble VR

MS Kinect 와 Leap Motion 만 알고 있었는데, 최근에 Oculus 에 인수된 Nimble VR 회사에 대한 소개가 있었다.

Oculus 에 인수되는 것을 목표로 만든 회사 같다는 생각이 들 정도로 DK2 에 맞춰서 만든 티가 역력하다. 마찬가지로 아직 베타 버전이다.

내 입장에서 Nimble VR 소식에 Leap Motion 을 계속 공부 해야 하는지 걱정이 안될 수 없었다. 어떻게 될지 모르니 계속 지켜봐야 할듯..



알바천국에서 (주)에이엠씨글로벌 이란 회사에서 자재,공수 계산 프로그램 개발 알바 공고가 떠서 부라부랴 프로필 업데이트해서 보낸후에 전화를 했다.

담당자가 다짜고짜 내일 10시 30분까지 안산에 있는 본사에 와서 업무설명을 들을 수 있는지 물어봤다. 내 이력이 마음에 들었나보다 싶어서 기쁜마음이 든 순간, 업무설명 자리가 미리 마련된것 같다는 생각이 들어서 자세히 물어봤는데 알바 지원한 사람들을 모두 모아놓고 업무 설명을 할 예정이라고 한다.

공공 프로젝트 수주 처럼 RFP 발표후 가격이랑 수행 능력을 기준으로 입찰 심사 하겠다는 소린데, 알바하러 온 개발자를 모아놓고 서로 경쟁을 시키는 상황이 너무 끔찍했다. 이런 경쟁은 업체 영업담당자가 할 몫으로 알고 있는데 말이다..  알바가 업체보다 싸고 마음대로 컨트롤 할 수있다는 장점 때문에 알바를 선택했으면 그에 맞는 행동을 해야 하는건 기본 아닌가? 대기업 갑질 횡포땜에 못살겠다고, 이래서 대한민국은 안된다고 하지 말고 자기들 부터 변화해야하는게 맞는게 아닌가? 이 업체가 너무 얄미웠고 황당했다.

뭐라고 욕을 한마디 해줄까 말까 망설이다가 귀찮기도 하고 만일 좋은 일로 연락이 올 수 있다는 생각이 들어서 주저하다가 한참만에 내일은 일이 있어서 어렵다고 했다. 뜻이 전해진건지, 아님 배가 부른건지 모르겠지만 이번에는 안되겠네요 하고 전화를 끊었다.

회사 홈페이지는 예쁘게 잘 만들었는데, 사람 대하는 기본 태도가 왜 이모양인지 모르겠다. 만일 알바 천국에 또 구인공고가 올라오면 통쾌하게 비웃어 주리라 !




 


알바천국에서 올라온 개발자 구인광고중 에어비엔와 똑같이 만들 개발자를 구하는게 있다. 주변에서 들은 예기는 있는지 초고난이도 라고 명기했는데, 급여가 200 이라고 한다. 전화해서 진심인지 물어볼까 말까 고민중이다
새벽에 잠이 깨서 다음tv팟 라이브를 뒤적였다. 볼게 없어서 퓨처라마마 다시보자는 생각에 선택했는데 못본 에피소드를 하고 있어서 생각지도 않게 횡재했다 싶었다.
릴리와 프라이 두사람만 제외하고 시간이 멈춘세상에서 두사람이 사랑하고 평생동안 세상을 여행하는 내용이었다. 물론 판스워드 박사가 다시 되돌려 놓긴 하지만..
늙어서 더이상 여행할 힘도 없는 두사람앞에서 판스워드 박사가 시간을 되돌리기 직전에 프라이는 릴라에게 평생동안 세상에 나 밖에 없어서 외롭지 않았냐고 물어 봤다. 릴라는 프라이가 있어서 평생동안 단한번도 외롭지 않았다고 하며 키스를 했다.

울컥해서 눈물이 날뻔했다. 웃으면서 만나는 사람은 많아도 돈 빌릴 친구하나 없는 외톨이 인생에 유일한 친구가 집사람이라서 그랬던것 같다.. 회사 땜에 늦고 술마시고 집에와서 짜증부리지 말아야 겠다는 생각을 다시 하게 되었다

어제 힐링 캠프에서 배우 이강우가 나왔다. 가장 기살리기 프로젝트 방송이라 재미가 없었지만, 그가 한 예기중 육아 일기가 마음에 와 닿았다. 사람보다 짧은 생애 때문에 짧은 강아지 시기의 일상을 보존하는게 의미가 있을것 같아서 블로그에 담기 시작하기로 했다.


===========================================


여튼, 김강우 한혜진 가족을 보다가 지쳐서 토르를 데리고 나왔다. 밤 12시 30분 조금 넘겼을까, 이 시간에는 자전거 산책로에 사람이 다니지 않아서 앞뒤로 사람이 다니지 않는지 확인하고 목줄을 풀어주고 산책을 시킨다. 사실, 늦은 시간에 목줄을 풀어주고 산책을 시작한건 얼마 되지 않는다. 토르가 개울에 뛰어 들거나 사람에게 달려들까봐 걱정되고 (그렇다고 물지는 않는다. 골든리트리버 견주들은 공감 할 것이다) 목줄을 묶고 사람들 사이를 다니는게 사회화 훈련의 중요한 부분 이라고 믿고 있었기 때문이다. 그런데 얼마전 늦은 시간에 집사람과 같이 산책을 나갔는데 집사람이 용감하게도 목줄을 풀었다. 그때도 이맘때라 사람이 다니지 않지만 돌발상황이 벌어지지 않을까 상당히 당황했었는데 예상 외로 토르는 적당한 간격을 유지하며 자유롭게 우리를 쫓아 오고 있었다. 목줄을 할 때는 나무 밑둥에 냄새를 맡느라 잡아 당겨도 버티던 녀석이 목줄이 풀리니까 "가자" 한 마디에 냄새를 맡다 말고 우리에게 달려 왔다. 이후로는 늦은 시간에 주민들이 잘 다니지 않는 자전거 산책로를 택해서 다니기 시작했다.


운동을 하니까 똥이 마려웠는지 가로등 밑에서 응가를 하는 동안 나는 주위를 둘러봤는데, 산책로 멀리서 골든 리트리버를 산책시키는 남성을 발견했다. 크기는 우리 토르 만했다. 혹시나 싸움이 벌어질까봐 (전에 사모예드를 산책시키러 나온 아가씨가 토르를 이쁘다고 만지다가 토르가 사모예드에게 물릴뻔 했다. 인터넷에 읽은 대로 사모예드는 질투가 강한 개 인것 같다) 얼른 목줄을 했는데, 가까이서 보니 붙임성이 넘치는 복실한 예쁜 골든리트리버(1년 7개월 암컷) 였다. 견주 성격이 좋아 보였고 다행히 서로 경계 안하고 놀고 싶어 하는것 같아서 목줄을 풀러줬다. 대형견 키우는 사람들은 도심 산책길에 다른 대형견을 만나기가 힘든 일이라 특별한 예기 없어도 상대편도 알아서 줄을 풀러 줬다.


이때까지 토르는 같은 크기의 같은 종의 개와 놀아본적이 없다. 여름 내내 자랐던 강원도 시골집 인근에 키우는 진도개는 비슷한 체구지만 평생 묶여 있어서 그런지 너무 사나워서 토르가 가까이 가질 못했고, 조금만 크면 개를 잡아먹는 그 아래 집의 강아지는 너무 작아서 토르의 장난을 받아 주기 역부족이었다. (전에 시골에 내려갈때 보니 그 강아지가 없었다. 주인 할아버지가 먹던 밥 찌끄러기 한그릇으로는 올 겨울 지독한 추위를 견디기에 버거웠던 같다..) 결국 강원도 에서도 앞마당에 고양이랑 같이 지내게 되었다. 고양이 예기는 다른 포스트에 하겠지만, 영리하고 성질 있는 놈이라 과격하게 들이대는 토르 오른쪽 눈을 긁어서 상처가 난적이 있다. 다행히도 안구는 다치지 않았고 지금은 상처가 다 아물어서 사라지는 중이다. 고양이는 개의 친구가 될 수 없어서 항상 걱정이었는데 오늘 그 소원을 풀었다. ㅎㅎ


두마리 개는 신나게 뛰어 다니고 있고, 나는 상대편 견주랑 나란히 걸어 가면서 짧지만 이런저런 예기를 했었다. (아침 햇살을 받고 있었 다면 영화의 한장면 이었을 것 같다) 상대편 견주는 내 나이 또래의 남성이었고 대형견(골든리터리버, 사모예드, 불독) 3마리를 키우는 사람이었다. 주방 일을 한다고 했는데 키우는 개들 때문에 산책로가 인접한 이 동네를 택했다고 했다.

산책로 중간에 제법 넓은 잔디밭이 있는데, 우리는 여기에 서서 개들이 마음껏 땅을 밟고 놀도록 했다. 나와 집사람은 토르가 계단을 무척 빠르게 뛰어 올라가서 다리가 튼튼하다고 여겼었는데 오늘 만난 녀석은 거의 적토마 급이였다. 토르가 지쳐서 딴청을 피우는건 처음이었다. 뭘 먹이냐고 물어봤는데, 직업이 요리사라서 조리하고 남은 생닭을 뼈만 발라서 준다고 했다. 

집에 가서 동영상 찍은거 보여주고 토르가 약하다고 예기하니까 집사람이 다음날 만원에 닭 3마리를 사와서 삶아서 살만 발라서 주기 시작했다. 역시 대한민국 엄마의 전투력은 전세계에서 최고인것 같다. ㅎㅎ

아직 설사병 이나 피부병 한번도 앓지 않아서 고맙지만, 앞으로 고기 잘 먹고 다리가 길게 자라서 길에서 만난 리트리버보다 잘 뛰었으면 한다. ㅎㅎ


개발 진행중 변경 내용을 게시한다.

Acobat Pro 8 에서 JPG 생성시 문제점

Acrobat Pro 8 에서 JPG 를 생성하면 포함된 텍스트 외곽선이 다음과 같이 추출된다. 

<< 원본 PDF >>


<< Acrobat Pro 8 에서 생성된 JPG >>


PNG 로 바꿔보기도 하고 설정을 변경해보기도 했지만, 포함된 이미지의 퀄리티와 색상만 향상될뿐 이었다.
Acobat Pro 8 에서 해결할 방법이 안보여서 할 수 없이 http://www.foolabs.com/xpdf 에서 제공하는 xpdf 를 사용했다.  PDF 표준을 정하는 곳과는 거리가 멀며, PDF 를 크래킹해서 xpdf 를 만들었다.
xpdf 는 몇가지 프로그램을 제공하는데, 이 중에 pdftoppm 을 이용해서 .ppm 파일을 생성한다음 ImageMagick 에서 png 로 변경하는 과정을 거치기로 했다.

ppm 파일은 포터블 비트맵 포멧을 말하며, 간단한 구조와 무압축(=무손실) 상태이므로 다른 포멧으로 변경하기 용이한 포멧이다.  ImageMagick 을 통해 png 포멧으로 만든 결과물이다.


pdftoppm 과 ImageMagic  을 통해 얻는 결과는 Photoshop PDF 파일을 열어서 얻는 결과와 비슷했다. (보기에 따라선 포토샵 보다 pdftpppm 과 ImageMagick  을 사용하는 것이 더 나아 보이기도 한다..) 
따라서, 1부에 만든 코드중 jpg 추출 부분은 다음과 같이 변경되었다.

조만간 Adobe 에 연락해서 방법이 없는지 문의할 예정이다. 긍정적인 답이 오면 바로 포스팅 하도록 하겠다. 이 글을 읽으시는 분들중 Acrobat Pro 로 해결하는 방법이 있으면 꼭 답변 주길 부탁 드린다.

소수의 개발자 이겠지만, 저와 똑같은 과정을 겪을 분들을 위해 포스팅 한다.

타겟 환경이 mac OS X 이지만, 손에 익은 에디터가 EditPlus 라서 윈도우에서 개발을 하고 mac 에 옮기는 는 프로세스로 개발을 했다. 개발을 중반쯤 넘길때 예상대로(=메뉴얼 대로) 동작하지 않는 부분이 발견되었다. 1주 반동안 고민의 고민을 거듭하고 셀수없는 검색과 시도를 했지만 해결하지 못한채 혹시나 하는 마음에 소스를 mac 에 복사했는데, 이럴수가.. 메뉴얼대로 동작을 하는 것이었다.!!  의미없이 보낸 시간이 너무 아까워서 화가 치밀어 올랐다.

다이얼로그를 안띄우고 실행하면 아래 코드가 올바르게 동작하는데, 메뉴얼에선 이에 관해 전혀 언급되어 있지 않다. 아도비가 알고서 그런건지 모르겠지만, saveAs 함수가 사용된 모든 예제들은 다이얼로그 없이 실행되는 것으로 되어 있다. 

나는 타겟 환경이 mac OS X 이라 이런 문제를 알 수 있었지만, 타겟 환경이 win 인 개발자들은 영문도 모른채 포기할것 같다는 생각이 들어서 급히 포스팅 한다.

app.execDialog() 함수를 실행해서 다이얼로그를 띄우고 버튼 이벤트 메소드에 다음과 같은 코드를 구현하면 다음과 같은 오류가 발생한다. 

oPDF = app.openDoc({
cPath: this.data.oRetn.cPath,
cFS: this.data.oRetn.cFS,
bHidden: true   // mac 에선 올바르게 동작. win 에선 화면이 나타남
});

oPDF.saveAs({
cPath : sPath
, cConvID : 'com.adobe.acrobat.accesstext'
, bCopy : true
, bPromptToOverwrite : false
});

// mac 에선 올바르게 동작. win 에선 다이얼로그가 닫혀질때까지 실행되지 않음.
// 50 페이지 이상 넘어가면 Acrobat 이 뻗게 됨.
oPDF.closeDoc(true);  



시작전에 비슷한 상황에 계신 분들에게 도움이 되고자 이 과정을 거친 이유에 대한 설명을 한다.

0. 본 프로그램은 서버용 프로그램이 아니다 사용자는 모두 mac os X 을 사용한다. 편집디자이너가 mac 과 pc 를 왔다 갔다 하는 불필요한 과정등을 없애기 위해 전임자가 개발한 win 용 프로그램을 걷어 내야 한다. 

1. 내가 속한 조직은 MS SQL Server 만 사용한다. 문제는, MS에서 mac os x 용 ODBC 드라이버를 만들어주지 않고 apple 또한 개발을 안하고 있다. (두 회사가 앙숙 임을 상기시켜 준다) 따라서 mac os x 에서 MS SQL Server 에 직접 붙을수는 없다. 물론 몇몇 공개 및 상용 드라이버가 있지만 두개 모두 100% 신뢰하냐는 질문에는 Never 다.

이에 관해 인터넷상에서 몇몇 분들이 MS 에서 제공하는것이 있다는 엉뚱한 답변으로 사람들을 혼란스럽게 하는것 같아서 추가로짚고 넘어간다. MS 에서는 win 용 ODBC 이외에 java native 4 드라이버만을 배포하고 있다. mac os X 이 java 를 지원하고 있으므로 사용 가능하다. 하지만, 이것은 java 프로그램을 할때만 사용할 수 있다.

win 용 Acrobat Pro 8 경우 javascript 에서 ADO 를 사용할수 있다. 그렇지만, 제공되는 기능이나 속도가 기대 이하였다. 게다가 이 기능은 CS3 제품중 Acobat Pro 만 유일하다.
IIS 올리는데 비용 부담이 없고 개발툴 역시 무료로 배포되는 Visual Studio Express 로 웹서비스 대부분의 기능은 개발이 가능하다. (게다가 한글화 까지..) JAVASCRIP 로 SOAP 을 이용하는 부분은 CS3 의 다른 제품(인디자인, 포토샵 등) 에서도 지원하며 사용법도 비슷하다. 나중을 위해서라도 도전해 보시길 바란다

2. 전임자가 윈도우 애플리케이션상에서 PDF 병합/분할 처리를 위해 pdftk 1.12 을 이용했다. 이 라이브러리의 큰 문제는 pdf 1.3 으로 변환된다는 것이다. PDF 풀컬러 인쇄를 하는 업체에선 문제가 된다. 자세한 내용은 다른 포스트에 성토 하겠다. 하여튼 안전하게 PDF 1.6 을 다루기 위해서는 Acobat Pro 나 할러퀸 같은 알만한 S/W 가 필요 하며, 회사에서 정품 CS3 를 가지고 있어서 Acobat Pro 8 을 사용한다.

3. Acobat Pro 8 의 javascript 엔진에서 SOAP 접근 및 PDF 결합/분리/Text 추출 등의 모든 작업과 간단한 화면 생성이 가능하다. 또한 메뉴에 넣을 수 있으므로 사용자가 편리하게 사용할 수 있다. 

블로그가 업무 보고를 하는 곳은 아니니 이정도로만 하고 본론에 들어가겠다.

환경은 다음과 같다.

클라이언트 : mac OS X Tiger. Acobat Pro 8 의 javascript 엔진 이용함.
서버 : win 2003 Server. Visual Studio 2008 에서 .Net 3.5 로 웹서비스 생성. (C# 사용)


아래는 IIS 에 올린 웹서비스 예제 코드다. Acobat Pro 8 의 JavaScript 엔진에서 이 메소드를 접근할 것이다.

// ASP.net 에서 생성한 테스트 코드
public string HelloWorld2(string d)
{
    return "Hello World" + d;
}


아래 코드는 Acobat pro 8 에서 웹서버에 접속해서 HelloWorld2() 를 호출하는 예제 이다.
Acobat pro 8 에서 ASP.NET 으로 생성된 웹서비스를 사용하는 경우, Net.SOAP.request  개체에서 반드시 설정할 두가지 속성이 있다. 두 속성을 지정하지 않으면 오류는 발생하지 않지만 파라메터가 전달되지 않는다.
(Acrobat 8 이후로는 SOAP 대신 Net.SOAP  으로 사용할것.)

// Acrobat javascript 코드
var cNameSpace = "http://10.10.1.1/";

var cTestString = { soapType : "xsd:string" , soapValue : "22" };
var req = {};
req["HelloWorld2"] = {d : cTestString};

var response = Net.SOAP.request({
        cURL: cNameSpace + "Service.asmx?WSDL"
        , oRequest : req
        , cAction : cNameSpace + "HelloWorld2"
        , bEncoded : false
        , cNamespace : cNameSpace
        , cResponseStyle: SOAPMessageStyle.Message
        , cVersion : SOAPVersion.version_1_2  
});

var value = response[0].soapValue[0].soapValue
console.println("result = " + value);

bEncoded :
ASP.NET 에서 생성되는 WSDL 은 Document/literal wrapped 을 사용하는데, Acrobat 의 SOAP 관련 javascript 개체들은 encoding 이 기본값이다. false 로 지정해야 한다.

cVersion :
asp.net 2.0 이상은 SOAP 1.1 요청이 있으면 1.1 형식으로 반환된다. 1.2 와 1.1 차이는 구글에서 검색하면 많은 정보를 얻을 수 있으므로 포스팅 하진 않는다.
Acrobat 8.0 이상을 사용한다면 반드시 SOAPVersion.version_1_2 로 설정하시기 바랍니다.


이정도면  Acrobat Pro 8 JavaScript 에서 ASP.NET WebService 를 이용하는데 큰 무리가 없을듯 하다.  자세한용은  "Developing Acrobat® Applications Using JavaScript" 이나 "JavaScript™ for Acrobat® API Reference" 를 보면서 참조하길 바란다.
프로그램적으로 PDF 를 결합/분할 해야 하는 미션을 부여받은 프로그래머들중 Acrobat Pro 가 없거나, Acrobat Pro 가 있다고 해도 능력에 벅차거나 공부하기 귀찮은 개발자들은 대부분 pdftk 을 사용하고 있는것 같다. 전임자는 후자쪽에 속하는 경우였고 그분이 사용하신 버전은  1.12 였다.

최근 인쇄품질 개선을 위해 몇가지 테스트를 하는중 알게된 내용중, pdftk 1.12 를 사용할경우 문제점에 대해 설명한다.

pdftk 1.12 를 사용하면 pdf 1.4 으로 변경된다.!!

Acrobat Pro 8 경우엔 pdf 1.7 까지 생성 가능하다. 대부분의 사람들은 PDF 는 다 똑같다고 생각하겠지만, 1.5 부터 8 device color 에서 31 device color 로 확장되었으며, 알파값(투명도) 인쇄가 가능해졌다. 거기에 더해서 링크 및 레이어 보존등 많은 기능이 추가되었다. 1.4 와 1.6을 비교해본 바로는 LCD 모니터상에서도 구별될 정도로 컬러 단계가 많이 세분화 되었다.

pdftk 의 장점은 단 하나. Acrobat Pro 8의 파일 결합에 비해 속도가 무척 빠르다는 것이다. 이유는 버전을 다운 시키고 최적화 및 중복 글꼴 제거, 웹에서 빠르게 보기 등을 전혀 하지 않기 때문이라고 생각 된다. 버전을 맞춘 상태에서 Acorbat pro 8 에서 생성된 결과를 비교하면 파일의 사이즈가 차이가 난다. 빠른게 장땡이 아니라는 의미다.

나는 개발 경력이 꽤 되지만, Acrobat 플러그인 개발이 쉽지만은 않은것이 사실이다. 하지만, 가장 중요한 것은 인쇄 품질이 향상된다는 것이다. 따라서 PDF 출력을 하는 조직에 속한 프로그래머는 이러한 내용을 어렵거나 또는 모른다고 외면하고 심지어 상사와 조직에게 사실을 감추지 않아야 될 것이다.


※얼마전 pdttk 을 배포하는 사이트에 가보니 버전이 올라갔다. 테스트하신 분들이 계시면 생성된 PDF 의 버전 및 결과에 대해서 답글 주길 바란다.

※최근에 pdf 를 이미지화 하는 방식 대신 백터 방식으로 처리하는 방식을 개발한 e-book 업체를 만나게 되었다. 이 솔루션은 링크 등의 정보를 추출해서 페이지에 링크를 거는 기능이 있다. PDF 가 링크 정보를 가지기 위해선 버전이 1.5 이상은 되어야 한다. 이북을 위해서라도 버전업이 필요한 시점이 올 수도 있다는 생각이 든다.

전임자가 만든 프로그램중 pdf 를 이미지(JPG)로 변환하는 프로그램이 있는데, 여러 가지 이유들로 걷어내고 새롭게 만들게 되었다. 나와 같은 상황에 처한 개발자들이 삽질하는 것을 막기 위해 글을 올린다.


블로그 제목이 Publishing Programming for Mac OS X 이지만, 몇가지 사정으로 이 프로그램은 Win 용 Acobat Pro 8 의 COM 인터페이스를 이용한 DLL 형태로 만들게 되었다. 이유부터 설명한다. 

MS SQL Server 상에 트렌젝션(데이터량) 이 크다. 트랜젝션이 크지 않았으면 DB 쪽 처리만 Mac OS X Server 에서 ASP.NET 기반의 SOAP 을 통해 처리했었을 것이다.

윈도우 기반 영업시스템에서 호출하거나 재사용이 가능해야 한다.


개발 환경은 다음과 같다.

win 용 Acrobat pro 8
Win 2003 Server
Win XP
Visual Basic 6
ImageMagick -6.4.8-10-Q8


각 작업별로 사용되는 라이브러리는 다음과 같다. DB 나 XML 을 사용하는 것은 MSDN 을 찾기 바란다.

pdf -> jpg 환  :  Acobat  Pro
pdf 의 텍스트 추출 : Acobat  Pro
변환된 jpg 의 썸네일 생성 : ImageMagick


Adobe CS3 는 windows Server 2003 이상에서만 설치된다. 2000 Server 에서 설치되는 편법이 있다고 들었지만 분명 이유가 있어서 OS 를 제한했다고 여겨진다. 설치를 진행하면서 알게된 사실인데, 서버에 설치되는 제품은 인디자인과  Acrobat Pro 8 정도 밖엔 안된다. 포토샵과 일러스트레터는 안깔린다.


▶ImageMagick

ImageMagick 은 이미지 변환툴중 역사도 오래되었고 꾸준한 업데이트가 이루어지고 있는 라이브러리다. 또한 mac OS X 및 파이썬, 루비 등의 최신 언어에서도 접근이 가능한 인터페이스를 제공하고 있다. http://www.imagemagick.org 에서 최신 버전을 받기 바란다. 나는 ImageMagick-6.4.8-10-Q8-windows-dll.exe 를 사용했다.
파일명을 주목하자. Q 은 Color Depth 를 말하며 Q8은 8bit , Q16은 16bit 를 말한다. 디카 RAW 포멧도 아니니 처리 속도나 메모리를 고려해서 Q8 을 사용하기로 결정했다.
아래는 설치화면이다. COM 인터페이스에서 이용하기 위해선 설치중 하단의 체크박스를 선택해야 한다. 


대부분의 경우 Microsoft Visual C++ 2008 SP1 Redistributable Package 가 설치되어 있지 않다. 다운로드 페이지의 하단에 보면 링크가 있으니 받아서 설치하도록 한다. 영문이지만 사이트에 친절하게 설명되어 있으니 조급해 하지 말고 차근히 읽어 보시길 바란다.

※ ImageMagick 는 경로명에 한글이 들어가면 실행이 안된다. 반드시 영문으로 폴더 명 파일명을 사용하기 바란다.



▶개발시 주의할 점.
vbs 는 디버그가 어려워서 vb6 에서 작업한다음 조금 수정해서 vbs 파일에 붙이는 과정을 거치고 있다. Acrobat Pro 의 경우 vb6 에서 참조 를 통해 Adobe Acrobat 8.0 Type Library 를 사용할때와 vbs 에서 CreateObject("") 를 통해 개체를 만들때 이름이 조금씩 다르다.
크게 다른것은 아니니까 당황하지 않길 바란다. 참고로 Acrobat SDK 에 포함된 문서의 모든 예제는 CreateObject() 를 이용하고 있다.



▶개발시 주의할 점.
아래 소스는 개발전 테스트를 위해 만든 소스 이다. 참고하길 바란다.

Option Explicit

Dim gApp, gAVDoc, gPDFDoc
Dim gPDFSel, gPDFRect, gPDFPV
Dim gPDFPage, gPDFHL

Set gApp = CreateObject("AcroExch.App")
gApp.Hide   '화면이 뜨는 경우를 막기 위해서 명시적으로 처리함.
Set gPDFRect = CreateObject("AcroExch.Rect")
Set gPDFHL = CreateObject("AcroExch.HiliteList")

Set gAVDoc = CreateObject("AcroExch.AVDoc")
gAVDoc.Open "C:\Documents and Settings\cynosure\바탕 화면\[007디자인1면]2009010185-16.pdf", ""
Set gPDFDoc = gAVDoc.GetPDDoc
Set gPDFPV = gAVDoc.GetAVPageView
Set gPDFPage = gPDFPV.GetPage

'내용 추출
gPDFHL.Add 0, 32767
Set gPDFSel = gPDFPage.CreatePageHilite(gPDFHL)

Dim lngint
Dim strValue
For lngint = 0 To gPDFSel.GetNumText - 1
   strValue = strValue & gPDFSel.GetText(lngint)
Next


'jpg 파일 저장
Dim aa
Set aa = gPDFDoc.GetJSObject()
Call aa.SaveAs("/d/kk.jpg", "com.adobe.acrobat.jpeg")  'Acrobat 6.0 부터 safe path 가 적용됨. 자세한 내용은 js_api_reference.pdf 의 "safe path" 를 참조하세요.
Set aa = Nothing


'썸네일 생성
Dim objIO
Set objIO = CreateObject("ImageMagickObject.MagickImage.1")
Call objIO.Convert("d:\kk.jpg", "-resize", "50x36^!", "d:\t_kk.jpg")   'command line 명령어중 스페이스를 기준으로 나눔
Set objIO = Nothing


'마무리
gAVDoc.Close False
gApp.Exit


'개체 삭제
Set gPDFHL = Nothing
Set gPDFRect = Nothing
Set gPDFDoc = Nothing
Set gAVDoc = Nothing
Set gApp = Nothing

'MsgBox "완료"




+ Recent posts