표시 객체 필터링 예제: Filter WorkbenchFlash Player 9 이상, Adobe AIR 1.0 이상 Filter Workbench에서 제공하는 사용자 인터페이스를 통해 이미지 및 기타 시각적 내용에 다양한 필터를 적용해 보고 ActionScript에서 동일한 효과를 내는 결과 코드를 확인할 수 있습니다. 이 응용 프로그램은 필터를 시험해 볼 수 있는 도구를 제공할 뿐만 아니라 다음과 같은 작업을 수행하는 방법도 보여 줍니다.
이 샘플에 대한 응용 프로그램 파일을 가져오려면 www.adobe.com/go/learn_programmingAS3samples_flash_kr를 참조하십시오. Filter Workbench 응용 프로그램 파일은 Samples/FilterWorkbench 폴더에 있으며 이 응용 프로그램은 다음과 같은 파일로 구성됩니다.
ActionScript 필터 시험하기Filter Workbench 응용 프로그램은 사용자가 다양한 필터 효과를 시험해 보고 이런 효과에 대해 관련 ActionScript 코드를 생성할 수 있도록 설계되었습니다. 이 응용 프로그램을 사용하면 비트맵 이미지 및 Flash에서 만들어진 애니메이션 등의 시각적 내용을 포함하는 세 가지 다른 파일을 선택할 수 있으며 선택한 이미지에 8개의 다른 ActionScript 필터를 개별적으로 적용하거나 다른 필터와 조합하여 적용할 수 있습니다. 응용 프로그램에는 다음 필터가 포함되어 있습니다.
사용자가 이미지와 이 이미지에 적용할 필터를 선택하면 응용 프로그램은 선택한 필터의 특정 속성을 설정하는 컨트롤이 있는 패널을 표시합니다. 예를 들어, 다음 이미지는 [경사] 필터가 선택된 응용 프로그램을 보여 줍니다. 사용자가 필터 속성을 조정하면 미리 보기가 실시간으로 업데이트됩니다. 사용자는 한 필터를 사용자 정의하고 [적용] 버튼을 클릭한 다음 다른 필터를 사용자 정의하고 [적용] 버튼을 클릭하는 방식으로 여러 개의 필터를 적용할 수도 있습니다. 응용 프로그램의 필터 패널의 몇 가지 기능과 제한 사항은 다음과 같습니다.
필터 인스턴스 만들기Filter Workbench 응용 프로그램에는 사용할 수 있는 필터별로 하나씩 지정된 클래스 집합이 포함되어 있는데 개별 패널은 이러한 클래스를 사용하여 필터를 만듭니다. 사용자가 필터를 선택하면 필터 패널과 연결된 ActionScript 코드에서는 해당하는 필터 팩토리 클래스의 인스턴스를 만듭니다. (이러한 클래스는 실제 팩토리에서 개별 제품을 만드는 것처럼 다른 객체의 인스턴스를 만들므로 팩토리 클래스라고 불립니다.) 사용자가 패널에서 속성 값을 변경할 때마다 패널의 코드는 팩토리 클래스의 해당하는 메서드를 호출합니다. 각 팩토리 클래스에는 패널이 적절한 필터 인스턴스를 만들 때 사용하는 특정 메서드가 포함되어 있습니다. 예를 들어 사용자가 [흐림] 필터를 선택하는 경우 응용 프로그램은 BlurFactory 인스턴스를 만듭니다. BlurFactory 클래스에는 blurX, blurY 및 quality라는 세 개의 매개 변수를 사용하는 modifyFilter() 메서드가 있는데 이 매개 변수는 원하는 BlurFilter 인스턴스를 만드는 데 함께 사용됩니다. private var _filter:BlurFilter; public function modifyFilter(blurX:Number = 4, blurY:Number = 4, quality:int = 1):void { _filter = new BlurFilter(blurX, blurY, quality); dispatchEvent(new Event(Event.CHANGE)); } 반면 사용자가 유연성이 훨씬 더 높은 [회선] 필터를 선택하는 경우 제어할 수 있는 속성 집합은 더 커지게 됩니다. 사용자가 필터 패널에서 다른 값을 선택하면 ConvolutionFactory 클래스에서 다음 코드가 호출됩니다. private var _filter:ConvolutionFilter; public function modifyFilter(matrixX:Number = 0, matrixY:Number = 0, matrix:Array = null, divisor:Number = 1.0, bias:Number = 0.0, preserveAlpha:Boolean = true, clamp:Boolean = true, color:uint = 0, alpha:Number = 0.0):void { _filter = new ConvolutionFilter(matrixX, matrixY, matrix, divisor, bias, preserveAlpha, clamp, color, alpha); dispatchEvent(new Event(Event.CHANGE)); } 각각의 경우에 필터 값이 변경되면 팩토리 객체는 Event.CHANGE 이벤트를 전달하여 리스너에게 필터 값이 변경되었음을 알립니다. 필터링된 내용에 필터를 실제로 적용하는 작업을 수행하는 FilterWorkbenchController 클래스는 필터의 새 복사본을 검색하여 필터링된 내용에 다시 적용해야 할 시기를 확인하기 위해 이벤트를 수신 대기합니다. FilterWorkbenchController 클래스는 각 필터 팩토리 클래스의 자세한 내용을 알 필요가 없으며 단지 필터가 변경되었음을 알고 필터의 복사본에 액세스할 수만 있으면 됩니다. 이를 위해 응용 프로그램에는 응용 프로그램의 FilterWorkbenchController 인스턴스가 작업을 수행할 수 있도록 필터 팩토리 클래스에서 제공해야 하는 비헤이비어를 정의하는 IFilterFactory 인터페이스가 포함되어 있습니다. IFilterFactory는 FilterWorkbenchController 클래스에서 사용되는 getFilter() 메서드를 정의합니다. function getFilter():BitmapFilter; getFilter() 인터페이스 메서드 정의에는 특정 유형의 필터가 아니라 BitmapFilter 인스턴스가 반환되도록 지정되어 있습니다. BitmapFilter 클래스는 특정 유형의 필터를 정의하지 않습니다. BitmapFilter는 모든 필터 클래스의 기본 클래스입니다. 각 필터 팩토리 클래스는 자신이 작성한 필터 객체에 대한 참조를 반환하는 getFilter() 메서드의 특정 구현을 정의합니다. 예를 들어 다음은 ConvolutionFactory 클래스 소스 코드의 단축된 버전입니다. public class ConvolutionFactory extends EventDispatcher implements IFilterFactory { // ------- Private vars ------- private var _filter:ConvolutionFilter; ... // ------- IFilterFactory implementation ------- public function getFilter():BitmapFilter { return _filter; } ... } ConvolutionFactory 클래스가 구현하는 getFilter() 메서드는 ConvolutionFilter 인스턴스를 반환하는데, getFilter()를 호출하는 객체는 이런 사실을 알 필요가 없습니다. ConvolutionFactory가 따르는 getFilter() 메서드의 정의에 따르면 이 메서드는 모든 ActionScript 필터 클래스의 인스턴스가 될 수 있는 BitmapFilter 인스턴스를 반환해야 합니다. 표시 객체에 필터 적용하기앞에서 설명한 대로 Filter Workbench 응용 프로그램은 선택한 시각적 객체에 필터를 실제로 적용하는 작업을 수행하는 FilterWorkbenchController 클래스의 인스턴스(이후 "컨트롤러 인스턴스"라고 함)를 사용합니다. 컨트롤러 인스턴스는 필터를 적용하기 전에 먼저 필터를 적용할 이미지 또는 시각적 내용에 대해 알고 있어야 합니다. 사용자가 이미지를 선택하면 응용 프로그램은 ImageType 클래스에 정의된 상수 중 하나를 전달하여 FilterWorkbenchController 클래스의 setFilterTarget() 메서드를 호출합니다. public function setFilterTarget(targetType:ImageType):void { ... _loader = new Loader(); ... _loader.contentLoaderInfo.addEventListener(Event.COMPLETE, targetLoadComplete); ... } 해당 정보를 사용하여 컨트롤러 인스턴스는 지정된 파일을 로드하고 이를 _currentTarget이라는 인스턴스 변수에 저장합니다. private var _currentTarget:DisplayObject; private function targetLoadComplete(event:Event):void { ... _currentTarget = _loader.content; ... } 사용자가 필터를 선택하면 응용 프로그램은 관련 필터 팩토리 객체에 대한 참조를 지정하여 컨트롤러 인스턴스의 setFilter() 메서드를 호출하고, 이 컨트롤러 인스턴스는 해당 참조를 _filterFactory라는 인스턴스 변수에 저장합니다. private var _filterFactory:IFilterFactory; public function setFilter(factory:IFilterFactory):void { ... _filterFactory = factory; _filterFactory.addEventListener(Event.CHANGE, filterChange); } 앞에서 설명한 것처럼 컨트롤러 인스턴스는 지정된 필터 팩토리 인스턴스의 특정 데이터 유형에 대해 알지 못하며 단지 이 객체가 IFilterFactory 인스턴스를 구현하므로 getFilter() 메서드를 가지고 있고, 이 메서드는 필터가 변경되면 change(Event.CHANGE) 이벤트를 전달한다는 것만 알고 있습니다. 사용자가 필터 패널에서 필터 속성을 변경하면 컨트롤러 인스턴스는 컨트롤러 인스턴스의 filterChange() 메서드를 호출하는 필터 팩토리의 change 이벤트를 통해 필터가 변경되었음을 확인합니다. 이 메서드는 다시 applyTemporaryFilter() 메서드를 호출합니다. private function filterChange(event:Event):void { applyTemporaryFilter(); } private function applyTemporaryFilter():void { var currentFilter:BitmapFilter = _filterFactory.getFilter(); // Add the current filter to the set temporarily _currentFilters.push(currentFilter); // Refresh the filter set of the filter target _currentTarget.filters = _currentFilters; // Remove the current filter from the set // (This doesn't remove it from the filter target, since // the target uses a copy of the filters array internally.) _currentFilters.pop(); } 표시 객체에 필터를 적용하는 작업은 applyTemporaryFilter() 메서드에서 발생합니다. 먼저 컨트롤러는 필터 팩토리의 getFilter() 메서드를 호출하여 필터 객체에 대한 참조를 검색합니다. var currentFilter:BitmapFilter = _filterFactory.getFilter(); 컨트롤러 인스턴스에는 _currentFilters라고 하는 Array 인스턴스 변수가 있는데 이 변수에는 표시 객체에 적용된 모든 필터가 저장되어 있습니다. 다음 단계는 새로 업데이트된 필터를 해당 배열에 추가하는 것입니다. _currentFilters.push(currentFilter); 그런 다음, 이미지에 필터를 실제로 적용하는 표시 객체의 filters 속성에 필터의 배열을 지정합니다. _currentTarget.filters = _currentFilters; 마지막으로, 가장 최근에 추가된 이 필터는 표시 객체에 영구적으로 적용되지 않아야 하는 "작업 중인" 필터이므로 이 필터는 _currentFilters 배열에서 제거됩니다. _currentFilters.pop(); 표시 객체는 filters 속성에 지정될 때 필터 배열의 복사본을 만들어서 원래 배열 대신 이 내부 배열을 사용합니다. 따라서 배열에서 이 필터를 제거해도 필터링된 표시 객체는 영향을 받지 않습니다. 따라서 필터의 배열을 변경해도 배열이 표시 객체의 filters 속성에 다시 지정될 때까지 표시 객체는 영향을 받지 않습니다. |
|