Flash platform2012/01/25 16:20

 Image Sprite Sheet는 게임이나 웹서비스에서 이미지를 불러올때 여러개로 나눠져 있는 이미지를 불러 오는 것 보다 하나의 이미지를 불러오는게 비교적 좋은 로딩 시간 또는 로딩 되는 파일 크기를 줄일수 있기 때문에 사용하는 방법이다. 많은 서비스에서 이미 CSS Sprite Sheet 를 이용하여 사이트에 포함 되어 있는 이미지를 하나의 이미지를 통해 불러 와서 사용함으로 로딩 타임을 줄이는 이점을 취하고 있다.


  • 이미지를 온라인에서 불러올 경우 요청 횟수를 줄일수 있다.
  • 여러 이미지를 하나의 이미지 파일로 만들기 때문에 이미지 크기를 줄일수 있다. (클수도 있다)
  • 하나의 이미지로 해당 어플리케이션의 스킨을 지정 할 수 있다. (해당 이미지만 교체 하면 스킨이 바뀐다)




Flash/Flex(이하 Flash)로 구현된 어플리케이션(이하 앱)들은 대부분의 이미지가 컴파일 타임에 임베딩 되기 때문에 로딩 시간 단축에 대한 장점은 줄어들겠지만, 메모리 관리 측면에서 보면 상당히 이득을 준다. 이 문서에서는 Flash 앱 개발시에 Image Sprite Sheet 를 만들어서 사용하는 방법에 대해 다룬다.



Image Sprite Tool


합쳐진 이미지를 사용하기에 앞서 Actionscript로 사용하기 편하게 이미지를 합쳐주는 툴이 필요 하다. 물론 수작업으로 해도 되지만, 이미 좋은 툴들이 나와 있으니 아래 나열된 툴중 무료를 사용하도록 하겠다. 툴은 어떤 것을 사용해도 상관 없지만 툴에서 만들어주는 이미지 퀄러티와 설명 파일형식을 고려 해야 한다.



Sprite Sheet Packer


Sprite Sheet Packer 는 아래 그림 처럼 이미지를 불러와서 하나의 png/jpeg/bitmap 파일로 만들어 준다. 또한 만들어진 이미지에 대한 좌표값을 가지고 있는 txt/xml 파일도 만들어 준다. 최대 단점은 윈도우에서만 된다는거;;





위와 같이 이미지를 추가한 뒤에 Image File 이름 Map File (합쳐진 이미지의 위치값에 대한 파일) 이름을 설정해 준뒤에 Build Sprite Sheet 버튼을 누르면 아래와 같이 두개의 파일이 생성 된다.



sample.png




sample.xml


sample.xml 과 sample.png 파일이 생성 되었다.




사용 방법


Sprite Sheet Packer 를 통해 이미지를 만들었다면 다음과 같은 방법으로 이미지를 사용할 수 있다.  (다른 툴을 이용했다면 해당 툴이서 출력해 주는 xml 또는 text 파일 형식에 맞게 수정해서 사용할 수 있다)


아래 Client Code 에서는 위의 툴을 이용하여 생성한 sample.png와 sample.xml 을 임베딩하여 ImageSpriteSheet.as 클래스를 사용하여 popup_bg를 불러와서 화면에 표시 하고 있다.



client code


package {
     
    import flash.display.Sprite;
    import flash.display.StageAlign;
    import flash.display.StageScaleMode;
    import flash.utils.ByteArray;
     
    public class ImageSprite_sprite extends Sprite {
         
        [Embed (source="/assets/sample.png")]
        private var IMAGE_SHEET:Class;
        [Embed (source="/assets/sample.xml", mimeType="application/octet-stream")]
        private var DATA_SHEET:Class;      
         
        public function ImageSprite_sprite()
        {
            super();
             
            // support autoOrients
            stage.align = StageAlign.TOP_LEFT;
            stage.scaleMode = StageScaleMode.NO_SCALE;
             
            init();
        }          
         
        private function init():void
        {
            // embed 한 xml과 png 파일을 로드 하여 파싱한다.
                        var xmlData:ByteArray = (new DATA_SHEET()) as ByteArray;
             
            var spriteSheet:ImageSpriteSheet;
            spriteSheet = new ImageSpriteSheet();
            spriteSheet.init(new IMAGE_SHEET(), XML(xmlData.readUTFBytes(xmlData.bytesAvailable)));
             
 
            // xml 에 정의 되어 있는 activity_indicator_160 을 불러와서 추가 한다.
            addChild(spriteSheet.getImage('popup_bg'));
             
        }
         
    }  
}





 ImageSpriteSheet Class


package {
    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.geom.Point;
    import flash.geom.Rectangle;
    import flash.utils.Dictionary;
     
     
    public class ImageSpriteSheet {
         
        private var _sheetImage:Bitmap;
        private var _sheetData:Dictionary;
         
        public function ImageSpriteSheet(){
        }          
         
        public function init(spriteSheet:Bitmap, sheetXML:XML):void {
             
            _sheetImage = spriteSheet;
            _sheetData = new Dictionary();
            parseSheetXML(sheetXML);           
        }
         
        private function parseSheetXML(data:XML):void {
             
            var i:int 0;
            var list:XMLList = data.Asset.Item;
             
            for(; i < list.length(); ++i) {
                 
                var key:String = list[i].Key;
                var value:Rectangle = parseImageBound(list[i].Value);
                _sheetData[key] = value;               
            }          
        }
         
        private function parseImageBound(data:String):Rectangle {
             
            var properties:Array =  data.split(" ");
            var bound:Rectangle;
             
            try {
             
                bound = new Rectangle(properties[0], properties[1], properties[2], properties[3]);
                 
            }catch(error:Error) {
                 
                throw new Error("Invalid data. please confirm data.");
            }
             
            return bound;
        }
         
        public function hasImage(name:String):Boolean {
             
            return (_sheetData[name])? true false;
        }
         
        public function getImage(name:String):Bitmap {
             
            if(hasImage(name)) {
                 
                var bound:Rectangle = _sheetData[name];
                var image:BitmapData = new BitmapData(bound.width, bound.height, true);
                image.copyPixels(_sheetImage.bitmapData, bound, new Point(00));
                 
                return new Bitmap(image);
            }
            else {
                 
                throw new Error("There is no image. named : "+name);
            }
             
            return null;           
        }
         
    }  
}



sample file download : ImageSpriteSample.zip


Image Sprite Sheet 를 사용하는 건 장점도 가지고 있지만, 디자인이 수정될때 마다 다시 생성해야 하는 번거로움도 가지고 있다. 하지만 실제로 앱에 적용하여 테스트 해보면 메모리 점유율 측면에서 많은 이득을 본다는걸 알수 있다. 다음 문서에서는 위의 Image Sprite Sheet 를 적용한 앱과 적용하지 않은 앱에 대해 비교해 보겠다.


검색을 통해 찾은 Sprite Sheet Packer 를 사용하였는데요. 더 좋은 툴을 아시는 분은 공유 부탁 드려요 :D



저작자 표시 비영리 변경 금지

'Flash platform' 카테고리의 다른 글

Flash App Performance : Image Sprite Sheet  (0) 2012/01/25
[Mobile] Flash Platform for Mobile  (0) 2010/09/19
Flex for Mobile Devices  (0) 2009/11/06
Flash / Flex 로 만든건 느리다?  (2) 2009/09/08
Posted by 동강
Flash platform2010/09/19 14:53

 몇일전 Apple 이 아이폰 앱 개발 정책 약관을 변경에 따라 다시 Flash CS5 를 이용하여 아이폰 앱 개발이 가능해 졌다. 정책이 바뀌기전 심사 중이었던 플래시로 만든 앱들도 심사 완료 상태가 되었다. 


 이 문서에서는 두가지,  Flash CS5 의 Package for iPhone 으로 개발하는 아이폰앱과 Adobe 에서 2011년 상반기 런칭을 목표로해서 개발하고 있는 Android for AIR 에 대한 소개 및 가능성에 대해 다룰 것이다. 


 먼저 Package for iPhone 이다. Flash Pro CS5를 이용해 만든 결과물이 아이폰 설치 파일인 .ipa 로 나온다. 개발자는 맥에서 xcode 와 object-c를 이용하여 개발한 .ipa 를 테스트하는 방법과 동일하게 자신의 아이폰에 설치 할 수 있다. 



(출처 : http://www.mikechambers.com/blog/ )


 단순히 Flash 툴을 이용해 ( Actionscript3.0 ) 만든 코드를 LLVM ( Low Level Virtual Machine ) 을 통해 .ipa 로 컴파일하는 것이다. 


 몇 가지 테스트를 해보니, 아이폰에서 제공하는 네이티브 API 를 사용하지 않는 컨텐츠라면 데스크톱 환경에서 사용하고 있는 소스를 아이폰 용으로 컴파일해서 사용해 보니 크게 퍼포먼스가 떨어지지 않는다. 다만 폰(스마트폰)이라는 디바이스적인 한계가 있기때문에 최적화가 필요 하다. 


최적화에 대한 내용은 어도비 에반젤리스트인 마이크챔버스의 블로그 내용을 참고하라.



 장점은 데스크톱에서 사용하는 플래시 컨텐츠의 소스를 그대로 가져다 쓸 수 있다는 점이다. 다만 데스크톱은 마우스를 이용하고 폰은 터치를 이용하는 점이 다를 뿐이지 소스를 전반적으로 수정할 필요는 없다. UI 를 구성하는 뷰단과 이벤트 처리만 바꿔준다면 손 쉽게 서비스가 가능한 앱을 만들수 있다. 




 단점은 굳이 플래시를 가지고 개발을 할 필요가 없다는 것이다. LLVM 의 성능이 향상된다면 컴파일되서 나오는 결과물의 퍼포먼스도 빨라지겠지만 xcode 와 object-c 를 이용하여 개발한 앱이 같은 기능을 한다면 더 빠르다. 그리고 데스크톱 자원을 사용해서 무리 없이 실행되던 게임들도 아이폰에서 실행 시키면 느릴수 있다. 아니 느리다. 퍼포먼스 튜닝이 반드시 필요한 부분이다. 하지만 모바일 용으로 퍼포먼스 튜닝을 한다면 데스트톱에서는 더 빠르게 실행 시킬수 있기 때문에 그 소스는 더 경쟁력이 생길 것이다. 


위의 단점들을 보면 굳이 Flash를 이용하여 아이폰 앱 개발을 할 필요성을 못느낀다. 하지만 같은 소스로 Android 앱까지 개발할수 있다면 생각이 달라질 것 같다.


현재 prerelease 상태로 Android OS 에 설치되는 AIR Runtime 이 개발 중에 있다. 아이폰 앱 개발과는 방법이 조금 다르지만 Flash CS5를 이용하여 안드로이드 앱을 개발하는 건 같다. 다만 안드로이드 OS 2.2 버전 이상에서 설치되며 폰에 AIR Runtime 을 설치해야만 Flash 로 개발한 앱을 설치 할 수 있다. 


자세한 개발 방법은 아래 사이트를 참고 하라.



위의 링크에서 확인할 수 있듯 많은 앱들이 이미 개발 되었다. 아직 prerelease 상태이기 때문에 Flash CS5 Android extention을 설치해야 한다. 설치는 AIR for Android prerelease program 에 가입한 후에 해당 사이트에 가면 다운로드 받을수 있다. 


Adobe AIR 가 폰에 설치되어 있어야만 Flash 로 만든 앱들을 설치 할 수 있다는 단점이 있지만, 이 부분은 정식 릴리즈가 되는 시점에서 해결책이 나올 것으로 본다. 몇가지 앱들을 넥서스원(Android 2.2)에 설치 해봤는데 성능이 기대보다 좋다. 개인적으로 아이폰 앱 보다는 안드로이드 앱 개발의 가능성이 높게 느껴 진다. 


다만, 아이폰과 안드로이드 해상도가 다르기 때문에 같은 뷰를 보여 주기 위해서는 소스 변경이 불가피 하고 안드로이드가 탑재되는 스마트폰도 역시 폰에 불가하기 때문에 성능 최적화가 필요 하다. 하지만, 이를 제외 하면 상당히 괜찮다. 아니 나쁘지 않다. 큰 리소스를 필요로 하는 앱이라면 네이티브 코드를 이용하여 개발하는게 휠씬 좋겠지만, 가벼운 컨텐츠 개발이라면 상당히 매력적인 기능이 될 것이다. 


하나의 코드를 이용하여, 데스트 톱( Windows, Mac, Linux), 모바일 ( 아이폰, 안드로이드 그리고 추가적으로 확장 예정인  OS ) 에서 모두 실행 될 수 있는 앱을 개발할 수 있다는게 Adobe가 내세우는 장점이고 나에게도 큰 장점으로 다가 온다. 다만 아직 갈 길이 많이 남아 있다. 퍼포먼스 측면에서 HTML5를 이용해서 개발한 것과 별 다를게 없다면 HTML5의 확장성에 밀리게 될게 뻔하기 때문이다. 하지만 네이티브 API가 접근 할 수 있다는 것 만으로도 상당히 큰 장점이 될 것이다. 그리고 소스를 재사용할 수 있다는 점은 인력 부족 상태에서 하나의 대안으로 자리 잡을 수도 있을것 같다. (또한 아직 prerelease 다 )


다음은 웹에서 서비스 하고 있는 소스를 이용해 뷰만 바꾼것을 아이폰과 안드로이드 앱으로 컴파일해서 설치해본 영상이다.






저작자 표시 비영리 변경 금지

'Flash platform' 카테고리의 다른 글

Flash App Performance : Image Sprite Sheet  (0) 2012/01/25
[Mobile] Flash Platform for Mobile  (0) 2010/09/19
Flex for Mobile Devices  (0) 2009/11/06
Flash / Flex 로 만든건 느리다?  (2) 2009/09/08
Posted by 동강
Flash platform2009/11/06 01:14

얼마 전에 MAX 2009 에서  Flex for Mobile Devices 라는 주제로 발표한 내용 입니다. 점점 Adobe Flash platform 의 모든 디바이스에 대한 지원이 가능해 지고 있는데요. PC 에서도 비교적 무겁다는 인식이 강한 Flex framework 가 과연 더 환경이 안좋은 Mobile 에서 어떤 퍼포먼스를 낼수 있게 될지 기대가 되네요.




저작자 표시 비영리 변경 금지
Posted by 동강
Flash platform2009/09/08 00:12

 이런 말을 많이 듣습니다.



Flash로 만들면 느리지 않아요? 

Flash 로 만드면 유지 보수가 힘들지 않아요?

Flash 로 만들면 오래 걸리지 않아요?? 




예전에는 Flash를 맹신하여 위의 말들에 "욱" 했었지만, 지금은 반반 입니다. 하지만 확실한건 Flash 로 만든 컨텐츠는

느리지 않다 입니다. 그러면 왜 느린가?? 왜 느리다고 생각하는 건가요?


느리게 만들기 때문에 느린 것이다.

느리게 만들게 의도 하기 때문에 느린 것이다.



 저는 이 두가지 이유 때문이라 생각 합니다. 첫번째 이유는 생각 없이 심볼 생성하고, 퍼포먼스 고려 없이 트윈 남발하고
어느덧 라이브러리에는 쓸데 없는 심볼이 쌓여서 SWF 자체로 무거워 지고, 여러 가지 Flash player 과부화 요소를 생각하지 않고 빨리 빨리 작업 해야 한다는 압박 때문에 그냥 그냥 지나가고... 두번째 이유는 생각 없는 클라이언트, 기획자, 디자이너 만나서 화려 한게 좋아요. Flash 는 화려 한거 아니에요? 트윈 떡 칠한거 보고 역시 Flash 는 달라요. 좀 더 화려 하게 해 주세요. 이 요구에 마지못해 따라가는 개발 때문이라는 생각이 드네요. 

 Flash 컨텐츠는 보통 생각하는 화려한 UI 외에도 많은 것들을 할 수 있습니다. 단순히 UI만 만드는 도구가 아니라는 거죠. 
ActiveX 를 대체해서 채팅 솔루션을 개발하기도 하고, 파일 업로도와 같은 것, 뮤직 플레이어, 동영상 플레이어 최근에 오픈한 네이버의 N드라이브나 뉴스 아카이브 등등 할 수 있는게 무궁 무진 합니다. 

 느리다고 생각하는건 Flash 컨텐츠를 너무 맹신해서 그런것 아닐까요? Flash 로 만들었을때 느리면 다른 걸로 만들면 느리지 않을까요? 

한밤 중에 고뇌 하고 있습니다.....


저작자 표시 비영리 변경 금지
Posted by 동강
Flash platform2008/12/11 16:07



Snapshot Explorer (click to launch)  

위의 예제에 대한 기술문서 링크

Posted by 동강
Flash platform2008/12/11 15:25

웹 관련 개발을 할때 가장 유용하게 쓰이는 플러그 인 중 하나는 Firefox 에서 플러그인으로 제공되는 Firebug 입니다. 이 Firebug 를 이용하여 Flash 를 디버깅하기 쉽게 도와주는 라이브러리를 소개 합니다.

 기존에 Firebug 에서는 console.firebug.toString(), console.log, console.debug, console.info, console.warn, console.error 명령을 통해서 디버깅에 도움을 주었습니다. 그 밖에도 Firebug 에서 더 유용하게 쓰이는 기능들이 있지만 Flashbug 에서는 이 console 기능을 통해 SWF 디버깅을 도와 줍니다.

 

Firebug 를 설치 하는 법

 

Javascript 에서는 아래와 같이 log, debug, info, warn, error 메소드에 따라 Firebug 에서 메시지를 다르게 표시해 줍니다.

Actionscript 와 같은 trace 가 없는 javascript 에서는 상당히 유용하게 쓰이게 됩니다.

 

그럼 Flash 에서는 왜 써야 되고 어떻게 사용되는 것인가..

Flash 자체에서 테스트를 한다면 물론 trace 를 사용하여 변수를 찍어 주면 됩니다. 하지만 실제로 서버에 올려서 테스트해 볼경우 trace 는 사용하지 못합니다. 딱히 SWF 안쪽에서 어떻게 돌아 가고 있는지 알수가 없을때 Flashbug 를 사용하면 됩니다. 

Flashbug 에서는 console 에서 제공하고 있는 메소드를 구현하고 있습니다. Flashbug 클래스 자체는 Singleton 으로 구현되어 있고 Static 클래스로 사용됩니다. ( 이 말은 생성할 필요 없이 공통으로 클래스 자체로 공통으로 사용된다는 의미 입니다.)  

사용법은 아래와 같습니다.


available();  : Firebug 의 사용 가능 유무를 true, false 로 반환함

log(msg); , debug(msg); : Firebug 에서 일반 로그 메시지를 출력함

info(msg); : i 로 표시 되어 지는 info 메시지를 출력함

warn(msg); : ! 로 표시 되는 warn 메시지를 출력함

error(obj:Object); : x 로 표시되는 error 메시지를 출력함       

Firebug 에서 확인한 결과는 다음과 같습니다.

위의 예제에 대한 사용 테스트는

http://dongkang.ivyro.net/testfolder/flashbug/Flashbug.html

가면 확인할수 있습니다. (물론 Firefox 에서만 확인 가능합니다.) 

Posted by 동강
Flash platform2008/12/11 15:21

Flex 에서는 기본적으로 component 옵션으로 tooltip 을 제공 하고 있지만, Flash 에서 툴팁을 만들어 쓰기란 여간 귀찬은

작업이 아닐수 없습니다. 그래서 Flash 기반의 쓸만한 tooltip 을 소개해 봅니다.

 

ToolTip.as

static 메소드로 이루어져 있는 하나의 툴팁 클래스로 스테이지나 오브젝트에 생성되는 모든 tooltip 들을 관리 합니다. 사용법은 간단합니다. 우선 사용 예제 부터 보시면 아래와 같습니다. 해당 target 에 대한 MouseEvent.MOUSE_OVER 만으로 이벤트를 처리 하게 됩니다.

Out 이벤트를 따로 처리할 필요가 없이 단지 Over 이벤트만 처리 하면 됩니다.


 

사용시 두단계를 거쳐야 합니다. 우선 첨부한 ToolTip.as 파일을 import 한 후에,

Tooltip 설명을 사용할 target 에 이벤트 리스너를 추가 합니다. ( tc_mc 를 target 으로 정했습니다.)

 

 

  1. import src.util.ToolTip;
  2. var toolTipAlign:String = "center";
  3. var toolTipAlpha:Number = .85;
  4. var toolTipDelay:int = 200;
  5.  
  6.  
  7. tp_mc.addEventListener(MouseEvent.MOUSE_OVER, Overhandler);

  8. ToolTip.init(stage,{text_align:toolTipAlign, opacity:toolTipAlpha, default_delay:toolTipDelay});  // Tooltip 초기화
  9. ToolTip.attach(evt.target, "")
  10. function Overhandler(evt:MouseEvent):void
  11. {
  12.          ToolTip.init(stage,{text_align:toolTipAlign, opacity:toolTipAlpha, default_delay:toolTipDelay});
  13.         ToolTip.attach(evt.target, "this is a sample");
  14.  
  15. }



1. ToolTip.init(툴팁의부모:stage,{text_align: 정렬값 , opacity:알바값, default_deday:툴팁이나타나는시간});

툴집을 위한 초기 값을 설정 합니다. 툴팁의 부모에는 툴집을 어디에 속하게 할 것인지 정하고(stage:Stage) 를 주로 사용합니다.

 

2. ToolTip.attach(툴팁을적용시킬target(tp_mc) ,"툴팁 설명" );

 

더 유동적으로 사용하고 싶은 분들은 소스를 훑어 보시면 될것 같습니다. 그리고 툴팁이 표시 되는 네모 상자가 마음에 안든다 하시는

분들도 reset_bg 메소드에서 그리고 있는 bg:Shape 를 자신이 라이브러리에서 만든 무비클립으로 Linkage 시켜 주던가,

graphics 클래스를 이용해서 좀 더 이쁘게 꾸밀수 있습니다.

테스트를 해 보니 몇가지 버그가 있어서 수정 합니다. 초기에 Mouse Over 했을때 Tooltip 이 발생안하는 것은 Tooltip 자체가 초기화가 안되어 있어서 (오브젝트를 Tooltip 으로 넘기고 바로 addEventListener 로 이벤트들을 걸어 주기 때문에 이벤트 발생 순서 상에 문제가 발생하게 됩니다. 그래서 강제로 초기화를 해 줘야 하는데 방법은 간단합니다.

위와 같이 Over 이벤트를 밖에 초기화 코드를 입력해 주시면 됩니다.


Posted by 동강