Posts tagged ·

as3

·...

Flash Gesture Recognition Demo – Mask Effect

no comments

요즘 한창 Image Processing에 관해서 공부를 하다가 제스처를 인식하여 마스크 효과를 적용해보면 어떨까하여 만들어 보았다. 이미지를 다루는 것이 아직도 서툴고 개념적으로 박히기에는 멀었다. 하지만 결과적으로는 재미있는 아웃풋이 나왔다.

우선, 제스처에 관련된 소스를 검색하여 개념을 익히는 일을 선행하였고, 이것을 어떻게 요리를 할 것인가에 대한 접근을 하면서 Step by Step으로 풀어나갔다.

코드의 중요 핵심은 제스처로 얻어낸 이미지를 어떠한 형태로 변형하여 마스크에 적용하느냐는 것이였다. 생각해 보면 그리 어렵지 않다고 판단했지만… 어려웠다.

우선 아래와 같이 Bitmap에 마스크를 적용할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
_image = new Bitmap(new NightImage(0, 0), "auto", true);
_image.x = 10;
_image.y = 10;
_image.width = _output.width;
_image.height = _output.height;
addChild(_image)
 
_mask = new Bitmap(new BitmapData(_output.width, _output.height));
_mask.x = 10;
_mask.y = 10;
addChild(_mask);
 
_image.mask = _mask;
_image.cacheAsBitmap = true;
_mask.cacheAsBitmap = true;

위에서 보면 단순하지만 이미지 데이터는 쉽게 마스킹이 되지 않는다.
이미지 속성에 마스크를 적용하기 위해서는 “white & black” 으로만 적용을 할 수가 있다.

그래서 아래와 같이 캠 화면에 찍힌 이미지에 필터를 적용하여 반전을 시켜 흰색만을 추출해 내야 한다.

1
2
3
4
5
6
7
8
_now.draw(_src, _mtx);
_now.draw(_old, null, null, BlendMode.DIFFERENCE);
 
_now.applyFilter(_now, _now.rect, new Point(), _col);
_now.applyFilter(_now, _now.rect, new Point(), _blr);
 
_now.threshold(_now, _now.rect, new Point(), '>', 0xFF333333, 0xFFFFFFFF);
_old.draw(_src, _mtx);

그리고 다음 코드와 같이 검은색을 알파 처리해서 적용하면 끝이다.

1
2
_mask.bitmapData.threshold
(_output.bitmapData, _output.bitmapData.rect, new Point(), '>', 0xFF000000, 0x00000000);

요번 작업으로 많은 이미지 데이터 처리가 존재한다는 것을 알게되었다.
이러한 효과를 여러가지 형태로 응용이 가능해 보인다.

작업을 하면서 느낀점은 빛에 대한 처리가 가장 힘들다.
그리고, 플래시의 캠 인식 속도가 느려서 많은 것을 시도하기에는 어렵다는 것이다.

결론적으로, 플래시로도 요번과 같은 인식에 대한 것들을 제작할 수 있지만
프로토타입핑 수준이라고 생각된다.

XML 데이터 중 엔터(\n) 적용하기

11 comments

오늘 작업을 하다가 XML 노드에 엔터 문자(\n) 적용이 안되어서 고생을 좀 했다.

var s:String ="Drama & \nMovie & \nAnimation";
trace(-1 < s.indexOf("\n"))

true

var xml:XML = <a>Drama & \nMovie & \nAnimation</a>
s = xml.toString();
trace(-1 < xml.indexOf("\n"))

false

XML 데이터는 ‘\n’ 문자를 왜 찾지를 못할까?
아마도 내부의 태그 중 무엇인가가 포장이 되어있을 것이다.

TextField에서는 이와 같은 경우가 눈으로 확인이 가능하다.
아래는 TextField를 생성하여 “엄진우”라고 입력하고, trace(TextFieild.htmlText) 한 결과다.

<TEXTFORMAT LEADING="2">
<P ALIGN="LEFT">
<FONT FACE="Dotum" SIZE="20" COLOR="#000000" LETTERSPACING="0" KERNING="1">
엄진우
</FONT>
</P>
</TEXTFORMAT>

위와 같이 “엄진우”란 글자를 htmlText 속성으로 넣고 출력하면,
텍스트 포멧 태그가 생성이 된다.

어쨌든, XML이 위와 같은 상태인지는 더 자세히 알아보려 했지만 작업을 해야하므로,
아래의 명령어로 아주 간단하게 치환을 시킬 수 있다.

바로 escape, unescape을 사용하여서 말이다.

아래의 메서드는 원하는 XML 값과 치환하고자 하는 값을 인자로 넘겨주면 된다.
즉, \n로 치환을하여 리턴을 해주므로 바로 text 속성에 대입을 하면 끝이다.

/** xml 데이터 중 치환하고자 하는 escape(String)을 넘기면 문자로 변환하여 반환함. */
function splitXMLToString( node:String = "", pat:String = "" ):String
{
	var s:String = escape(node) ;
	var a:Array = s.split(pat); // "%5Cn" == /n
	var leng:int = a.length;
 
	for (var i:int = 0; i < leng; i++)
	{
		a[i] = unescape(a[i])
	}
 
	return a.join("\n");
}
var xml:XML = <test>엄\n진\n우</test>;
tf.text = splitXMLToString(xml.toString(), escape("\\n")) as String;

아래와 같은 텍스트 필드 결과가 출력된다.

엄
진
우

이런 방식 말고, 다른 류가 존재한다면 코멘트를 달아주면 감사. ^^

마우스 이벤트 제어 (mouseChildren, mouseEnabled)

no comments

작업을 하다 보면 마우스 이벤트에 많은 문제점이 발견된다. 관련 글 들도 오래전 부터 무수하다.

요번 프로젝트 작업에서도 실수로 mouseChildren 때문에 오버 이벤트를 놓쳐서 인터렉션 효과와 마우스 이벤트 미스 오류를 발생하여 이렇게 글을 작성하게 되었다. 디버깅? 시간을 상당히 소요하는 경우가 생겼기 때문이다.

내가 실수 한 것은 “객체.mouseEnabled = false” 하면 내부에 모든 것들이 enabled 될 것이라고 착각을 해버린 것이다. 내부의 객체들이 존재하면 그 객체에도 mouseEnabled 속성이 존재하기 때문에 상위 객체에서 “객체.mouseChildren = false”를 사용하여 내부 객체 이벤트를 비활성화 시켜서 하위 레이어에 있는 객체의 이벤트를 체크할 수 있다. 아래는 상위 객체인 “upper.mouseChildren = false”를 하지 않은 경우이다.

우선, 아래의 예제를 보면 lower(파랑 박스)를 버튼 모드를 활성화 시킨 것이다.
(MOUSE_OVER, CLICK 효과가 적용되어 있음.)

위에서 보면 lower와 중첩되어있는 상위 레이어의 upper가 문제이다.
upper는 아래와 같이 최초 셋팅이 되어있기 때문에 하위 레이어의 lower의 버튼 이벤트를 받을 수 없다.

this.upper.mouseChildren = true;
this.upper.mouseEnabled = true;

그래서 아래와 같은 클래스를 만들어서 자신의 내부에 있는 객체들을 최초에 마우스 이벤트에 대해서 비활성화를 시켰다.

package
{
 
	import flash.display.DisplayObjectContainer;
 
	/**
	 * @author jin_u [ jin_u@jinustudio.com | www.jinustudio.com ]
	 * @since 2010.06.27
	 * @version 1.0.0
	 *
	 * MouseEvent : Enabled Class.
	 *
	 * useing : mouseEnabled = false, mouseEnabled = false
	 * 	Enabled(new Enabled).target(this).enabled(false, false);
	 * useing : mouseEnabled = false, mouseEnabled = true
	 * 	Enabled(new Enabled).target(this.targetObject).enabled(false, true);
	 */
	public class Enabled
	{
		private var docChild:DisplayObjectContainer;
 
		public function target (_child:DisplayObjectContainer = null):Enabled
		{
			this.docChild = _child;
			return this;
		}
 
		public function enabled (_isChildren:Boolean = false, _isEnabled:Boolean = false):Enabled
		{
			if ("mouseChildren" in this.docChild) this.docChild.mouseChildren = true;
			if ("mouseEnabled" in this.docChild) this.docChild.mouseEnabled = true;
 
			var child:*;
			var leng:int = this.docChild.numChildren;
			var i:int = 0
			while ( i &lt; leng)
			{
				child = this.docChild.getChildAt(i);
				if ("mouseChildren" in child) child.mouseChildren = _isChildren;
				if ("mouseEnabled" in child) child.mouseEnabled = _isEnabled;
				i ++
			}
			return this;
		}
	}
 
}

아래와 같이 코드를 컨스트럭터에 적용을하면 이벤트가 모두 제거된다.

package
{
	...
 
		public function EnabledCheck()
		{
			/** 도큐먼트의 모든 객체에 mouseChildren, mouseEnabled을 비활성화 시킨다. */
			Enabled(new Enabled).target(this).enabled(false, false);
			/** this.lower 내부의 모든 객체에 mouseEnabled만 활성화 시킨다. */
			//Enabled(new Enabled).target(this.lower).enabled(false, true);
 
			...
		}
 
		...
 
	}
 
}

그리고 내가 원하는 lower만을 활성화 시켜주면 아래와 같이 효과가 이루어진다.

/** 도큐먼트의 모든 객체에 mouseChildren, mouseEnabled을 비활성화 시킨다. */
Enabled(new Enabled).target(this).enabled(false, false);
/** this.lower 내부의 모든 객체에 mouseEnabled만 활성화 시킨다. */
Enabled(new Enabled).target(this.lower).enabled(false, true);

나는 비주얼쪽으로 작업을 많이 하는 편이다. 객체의 모션의 흐름에 대한 이벤트 제어를 많이 주다 보면 마우스 이벤트 처리가 엉키는 경우를 종종 발생한다. 그래서 이와 같은 경우에 상당히 민감하다.

비단, 비주얼 개발이 아닌 애플리케이션 개발에서도 이 부분이 상당히 민감한 부분이라 많은 토론들이 오고가는 것을 보았다. 리스너는 적당히 사용하고 지우는 것이 최고인듯.

여러군데의 포스트들을 보았고, 코드 참조와 방법을 생각을 해보았다.
현재는 이 방법이 괜찮아 보인다. 더 좋은 방법이 있다면 개선해서 사용하면 좋을 듯 싶다.

참고로 디스플레이 객체중 Bitmap 같은 경우는 DisplayObject와 바로 상속 관계에 있는 객체는 이벤트 속성이 존재하지 않으므로 단독적으로 사용을 할때는 이와 같은 예외 처리를 할 필요는 없다.

참고 및 관련 사이트 :
이벤트 전파
마우스, 키보드의 인터렉션 최적화 1/2
Ticore’s Blog: AS3 MouseEvent.relatedObject
AS3 Trick – adjust double click time by hacking event flow