본문 바로가기

Mashup.OpenAPI

[매쉬업] Openapi 를 이용한 이미지 검색


우선 발급 받은 APIKEY 는 요청을 보낼 때 같이 보내게 됩니다. 

예를 들어 

http://openapi.naver.com/search?key=***&query=go&target=image&start=1&display=10   

위의 URL 에서 전달 하는 변수와 같이 image 검색을 위해서는 꼭 전달해야 되는 변수들이 존재 합니다.

 (출처 : http://openapi.naver.com/page.nhn?PageId=1_15 )
 
1. 요청 URL (request url)
   http://openapi.naver.com/search
2. 요청 변수 (request parameter)
요청 변수 설명
key string (필수) 이용 등록을 통해 받은 key 스트링을 입력합니다.
target string (필수) : image 서비스를 위해서는 무조건 지정해야 합니다. (image 검색 지정)
query string (필수) 검색을 원하는 질의, UTF-8 인코딩 입니다. (검색어)
display integer : 기본값 10, 최대 100

검색결과 출력건수를 지정합니다. 최대 100까지 가능합니다.

한번에 검색을 원하는 양 지정

start integer : 기본값 1, 최대 1000

검색의 시작위치를 지정할 수 있습니다. 최대 1000까지 가능합니다.

'플래시 를 검색 했다면 그 양은 엄청 많은 것입니다. 그때 검색한 양에서 어느부분 부터 출력을 해 줄것인가를 나타 냅니다.

sort string : sim (기본값), date 정렬 옵션입니다.
sim : 유사도순(기본값)
date : 날짜순
filter string : all (기본값), large,
midium, small
사이즈에 따른 필터 옵션입니다.
all : 전체 이미지(기본값)
large : 큰 이미지만 제공
medium : 중간 이미지만 제공
small : 작은 이미지만 제공

샘플 URL
   http://openapi.naver.com/search?key=test&query=go&target=image&start=1&display=10
 

우선 fla 파일을 만들고 Componnent 창에서 TextInput 을 Stage 에 올려 놓습니다. 그리고 name 을 input_txt 라 합니다. 그리고 난 후에 main 이라는 Document class 를 만들고, NaverImageApi 라는 as 파일을 만듭니다. 그냥 생성만 해 놓으시면 됩니다.  

그리고 main.as 와 fla 파일을 연결 합니다. (fla 파일의 Document class 를 main.as 로 지정 합니다. 이 과정을 모르신다면 이글을 참고 하세요. http://blog.naver.com/dongkang0626/130027969217  

이렇게 생성이 끝나고 TextInput 에 검색을 하면 해당 질의를 서버 측에 보내는 작업을 하기 위해 main.as 를 정리 하겠습니다.

 main.as
 
  1. package
  2. {
  3.         import flash.display.Sprite
  4.         import fl.events.ComponentEvent;
  5.        
  6.         public class main extends Sprite
  7.         {
  8.                 public function main()
  9.                 {
  10.                         input_txt.addEventListener(ComponentEvent.ENTER, onInputEnterhandler);
  11.                 }
  12.                 private function onInputEnterhandler(ev:ComponentEvent):void
  13.                 {
  14.                         trace("엔터");
  15.                        
  16.                 }
  17.                
  18.         }
  19.        
  20. }
  21.  

 ComponentEvent.ENTER 은 Component 에서 Enter 가 발생 하는지 감시해 주는 이벤트 입니다. KeyboardEvent 를 쓰는거에 비해 코드가 줄어 들지요.ㅎ 위와 같은 작업을 하면 input_txt 에 커서를 올려 놓고 Enter 를 쳤을때 "엔터" 가 출력 되는걸 확인할 수 있습니다.  

추가로 해 줘야 하는 부분은 이미지를 검색할 객체를 만들어 주는 부분 입니다. 위에서 만든 NaverImageAPI.as 를 가지고 검색 쿼리를  보낼 것 입니다. 그러기 위해서는 NaverImageAPI 객체를 생성합니다.

 
  1. package
  2. {
  3.         import flash.display.Sprite
  4.         import fl.events.ComponentEvent;
  5.        
  6.         public class main extends Sprite
  7.         {      
  8.                 private var imageloader:NaverImageApi;
  9.                 public function main()
  10.                 {
  11.                         imageloader = new NaverImageApi();
  12.                         input_txt.addEventListener(ComponentEvent.ENTER, onInputEnterhandler);
  13.                 }
  14.                 private function onInputEnterhandler(ev:ComponentEvent):void
  15.                 {
  16.                         trace("엔터");
  17.                 }
  18.                                
  19.         }
  20.        
  21. }

 main.as 에 대한 준비가 끝났습니다. 이제 검색 쿼리를 보내기 위해 NaverImageApi 클래스에 public function 을 선언하여 그 함수를 main.as 에서 사용하는 방식으로 코딩을 해 보겠습니 다.  

 NaverImageApi.as
 
  1. package
  2. {
  3.         import flash.display.*;
  4.         import flash.events.*;
  5.         import flash.net.*;
  6.         import flash.xml.*;
  7.        
  8.                
  9.         public class NaverImageApi extends EventDispatcher{
  10.                 private var mInfo:Object;// OpenAPI 를 쓰기 위한 준비 내용이 들어 있다.
  11.                                     
  12.                 // constructor
  13.                 public function NaverImageApi():void {// 초기화 시킨다.
  14.                                        
  15.                         mInfo={apiURL:"http://openapi.naver.com/search?target=image",
  16.                                         apiKey:"7ad7237d57e7290e8a136d05bfdda2dc",
  17.                                         query:"",
  18.                                         displayNum:10};
  19.                        
  20.                 }
  21.                
  22.                 // main function
  23.                 public function main_loadPage(_page:Number,_query:String):void {// 메인 페이지가 로드 될때 불러와 진다.
  24.                 }
  25.          }
  26. }

우선 mInfo Object 를 정의한 후 쿼리를 날리는데 필요한 변수들을 모아서 저장 합니다. 이때 query 는 input_txt 에서 불러서 쓸 것이기 때문에 빈칸으로 저장 합니다. 그리고 검색 쿼리를 날리기 위한 함수 main_loadPage 를 선언합니다. 여기에서 _page 를 선언 하는 이유 는 이미지 페이지 순서에 따라 다음 이미지나 이전의 이미지를 검색 하기 위한 변수 입니다.  

  1.                 public function main_loadPage(_page:Number,_query:String):void {
    // 메인 페이지가 로드 될때 불러와 진다.
  2.                         var page = _page + 1;
  3.                         api_load(_query,page,mInfo.displayNum);
  4.  
  5.                 }
  6.                
  7.                 // API load function
  8.                 private function api_load(_query:String,_page:Number,_displayNum:Number):void {
  9.                        
  10.                 }

main_loadPage 에 api_load 라는 함수를 콜하고 (검색어, 페이지, 검색갯수) 를 넘겨 줍니다. api_load 함수에서는 이들 변수를 받아와서 URLLoader 를 이용하여 쿼리를 서버측에 보내게 됩니다. 

  1. private function api_load(_query:String,_page:Number,_displayNum:Number):void {
  2.                        
  3.                         var page = _page*_displayNum;
  4.                         var loader:URLLoader=new URLLoader  ;
  5.                         loader.addEventListener(Event.COMPLETE,api_loadComplete);
  6.                         loader.addEventListener(IOErrorEvent.IO_ERROR,api_loadError);
  7.                         var requestURL=mInfo.apiURL + "&key=" + mInfo.apiKey + "&query=" +encodeURI(_query) + "&start=" + page + "&display=" + _displayNum;
  8.                        
  9.                         var request:URLRequest=new URLRequest(requestURL);
  10.                         loader.load(request);
  11.                         //
  12.  
  13.                 }

 URLLoader 와 Loader 의 사용법은 비슷하니 URLLoader 를 모르시는 분은 Loader 라고 생각하셔도 무방 합니다. 
로드가 끝났을때의 이벤트와 api_loadComplete , 에러가 났을때의 이벤트 api_loadError 를 설정한 뒤에 requestURL 으로 위에서 보았던 image 쿼리를 보내는 방식에 맞게  ( http://openapi.naver.com/search?key=test&query=go&target=image&start=1&display=10 )

load 합니다 위에서 mInfo 를 정의한 이유는 requestURL 때문 이었습니다. 

load 가 끝나면

  1. private function api_loadComplete(event:Event):void {
  2.                        
  3.                         trace("api load complete");
  4.                         var loader:URLLoader=URLLoader(event.target);
  5.                         outXMLdata = new XML(loader.data);
  6.                         trace(outXMLdata);              
  7.                         dispatchEvent(new Event(Event.COMPLETE));
  8.                         // 컨테이너에 연결 시킨다.
  9.                        
  10.                 }

이 함수가 실행 되어 보낸 퀴리에 해당 하는 xml 데이터를 받아 오게 됩니다. 그리고 main 함수에 쿼리전송에 대한 응답이 완료 되었다는 것을 알리기 위해  dispatchEvent(new Event(Event.COMPLETE)); 를 사용하여 main 에서 접근 할 수 있도록 정의해 줍니다.

dispatchEvent 를 통해 main 에서 NaverImageApi class 의 이벤트에 대한 접근이 가능해 졌습니다. dispatcherEvent 를 모르시면

이 글을 참고 하세요 http://blog.naver.com/dongkang0626/130031128965 

main.as 는 조금만 수정 하면 됩니다.

 main.as
 
  1. package
  2. {
  3.         import flash.display.Sprite
  4.         import fl.events.ComponentEvent;
  5.        
  6.         public class main extends Sprite
  7.         {      
  8.                 private var imageloader:NaverImageApi;
  9.                 public function main()
  10.                 {
  11.                         imageloader = new NaverImageApi();
  12.                         imageloader.addEventListener(Event.COMPLETE, onLoaderComplete);
  13.                         input_txt.addEventListener(ComponentEvent.ENTER, onInputEnterhandler);
  14.                 }
  15.                 private function onInputEnterhandler(ev:ComponentEvent):void
  16.                 {
  17.                         trace("엔터");
  18.                 }
  19.                 private function onLoaderComplete(ev:Event):void
  20.                 {
  21.                         trace("로드끝");
  22.                        
  23.                 }
  24.                
  25.         }
  26.        
  27. }

 imageloader 에 dispatchEvent 를 걸었으니 addEventListener(Event.COMPLETE, function ) 으로 이벤트를 받아 올 수 있습니다.  

이제 xml 을 받아 오는 모든 작업이 완료 되었습니다. main.as 에 대한 완성 코드는 위와 같고, NaverImageApi.as 에 대한 완성 코드는 다음과 같습니다.

 NaverImageApi.as
 
  1. package
  2. {
  3.         import flash.system.System;
  4.         import flash.display.*;
  5.         import flash.events.*;
  6.         import flash.net.*;
  7.         import flash.xml.*;
  8.        
  9.                
  10.         public class NaverImageApi extends EventDispatcher{
  11.                 private var mInfo:Object;// OpenAPI 를 쓰기 위한 준비 내용이 들어 있다.
  12.                 public var outXMLdata:XML;
  13.                        
  14.                 // constructor
  15.                 public function NaverImageApi():void {// 초기화 시킨다.
  16.                                        
  17.                         mInfo={apiURL:"http://openapi.naver.com/search?target=image",
  18.                                         apiKey:"7ad7237d57e7290e8a136d05bfdda2dc",
  19.                                         query:"",
  20.                                         displayNum:30};
  21.                        
  22.                 }
  23.                
  24.                 // main function
  25.                 public function main_loadPage(_page:Number,_query:String):void {// 메인 페이지가 로드 될때 불러와 진다.
  26.                         var page = _page + 1;
  27.                         api_load(_query,page,mInfo.displayNum);
  28.  
  29.                 }
  30.                
  31.                 // API load function
  32.                 private function api_load(_query:String,_page:Number,_displayNum:Number):void {
  33.                        
  34.                         var page = _page*_displayNum;
  35.                         var loader:URLLoader=new URLLoader  ;
  36.                         loader.addEventListener(Event.COMPLETE,api_loadComplete);
  37.                         loader.addEventListener(IOErrorEvent.IO_ERROR,api_loadError);
  38.                         var requestURL=mInfo.apiURL + "&key=" + mInfo.apiKey + "&query=" +encodeURI(_query) + "&start=" + page + "&display=" + _displayNum;
  39.                        
  40.                         var request:URLRequest=new URLRequest(requestURL);
  41.                         loader.load(request);
  42.                         //
  43.  
  44.                 }
  45.                 private function api_loadComplete(event:Event):void {
  46.                        
  47.                         trace("api load complete");
  48.                         var loader:URLLoader=URLLoader(event.target);
  49.                         var dataXML = new XML(loader.data);
  50.                         outXMLdata = dataXML;
  51.                        
  52.                         dispatchEvent(new Event(Event.COMPLETE));
  53.                         // 컨테이너에 연결 시킨다.
  54.                        
  55.                 }
  56.                 public function get xml():XML
  57.                 {
  58.                         return outXMLdata;
  59.                        
  60.                 }
  61.                 private function api_loadError(error:IOErrorEvent):void {
  62.                         trace("api load error");
  63.                                                
  64.                 }
  65.                                
  66.         }// End Class
  67. }

추가된 사항은 get xml() 을 이용하여 받아온 xml 을 접근 하기 위해 함수를 만들었다는 점입니다. 아차! main.as 에서 검색 했을때 NaverImageApi 에 있는 함수를 출력해 주는 부분을 깜박 했네요.  

  1. private function onInputEnterhandler(ev:ComponentEvent):void
  2.                 {
  3.                         trace("엔터");
  4.                         imageloader.main_loadPage(1,input_txt.text);
  5.                 }

검색의 1page 에 해당하는 부분을 로드해 줍니다.

 main.as
 
  1. package
  2. {
  3.         import flash.display.Sprite
  4.         import flash.events.Event;
  5.         import fl.events.ComponentEvent;
  6.        
  7.         public class main extends Sprite
  8.         {      
  9.                 private var imageloader:NaverImageApi;
  10.                 public function main()
  11.                 {
  12.                         imageloader = new NaverImageApi();
  13.                         imageloader.addEventListener(Event.COMPLETE, onLoaderComplete);
  14.                         input_txt.addEventListener(ComponentEvent.ENTER, onInputEnterhandler);
  15.                 }
  16.                 private function onInputEnterhandler(ev:ComponentEvent):void
  17.                 {
  18.                         trace("엔터");
  19.                         imageloader.main_loadPage(1,input_txt.text);
  20.  
  21.                 }
  22.                 private function onLoaderComplete(ev:Event):void
  23.                 {
  24.                         trace("로드끝");
  25.                        
  26.                 }
  27.                
  28.         }
  29.        
  30. }

 그럼 검색을 해 볼까요? 

위와 같이 이미지 정보를 포함한 xml 이 로드 됩니다. 이 정보들을 이용해서 Loader 를 통해 이미지를 불러 올 수도 있고 여러 가지 재미난 작업들을 할 수 있습니다. 

flickr 이미지 api 를 이용한 예 http://www.pimpampum.net/phrasr/?id=10772

 

Papervision3D 를 이용한 이미지 검색 ( 검색어를 입력 하세요. )

매쉬업에 관심을 가지게 된 계기는 얼마 안되었지만, 하면 할 수록 재미있고 신기 한것들을 만들 수 있는것 같습니다. 물론 직접 서비스가 되는 것도 가능 합니다. 앞으로 여러 매쉬업 하는 방법에 대해 소개 하면서 Flash 를 이용한 매쉬업 관련 컨텐츠가  많이 나왔으면 하는 바램입니다.