tag:blogger.com,1999:blog-69349493776589660402008-08-29T00:19:55.094+08:00Ticore's BlogFlash、Flex、ActionScript 相關研究心得{id: "Ticore"}; //http://www.blogger.com/profile/01433005931305983346noreply@blogger.comBlogger8125tag:blogger.com,1999:blog-6934949377658966040.post-5486556577691457112008-07-05T20:07:00.008+08:002008-07-14T18:14:18.828+08:002008-07-14T18:14:18.828+08:00AS3 - BitmapText 程式分享<p align="right" class="author"><a href="http://ticore.blogspot.com/">Ticore's Blog</a></p>
<p>
由於 Flash Player 一直以來都無法對系統字體的文字作旋轉與不規則形狀遮罩<br/>
可是到了 Flash Player 9 AS3,可以將文字繪製成點陣圖<br/>
也可以自行繼承內建類別 Sprite, TextField 等<br/>
於是想到做一個 TextField Wrapper,提供系統文字的點陣化功能<br/>
藉以達到文字可旋轉、套用不規則遮罩
</p>
<p>
其實這個 BitmapText 程式去年就已經寫了<br/>
主要是出於研究目的<br/>
專案一次也沒有用到過<br/>
沒想到最近新出的 Flash Player 10 beta 文字引擎<br/>
已經可以使用系統字體作旋轉了<br/>
倘若再不把這程式拿出來使用一下,恐怕就這樣永不見天日了~~><
</p>
<span class="fullpost">
<p>
主要是包含兩個類別 TextWrapper, BitmapText<br/>
TextWrapper 只是 TextField 的外覆類別<br/>
真正在做點陣繪圖的是 BitmapText<br/>
由於 AS3 TextField 成員屬性與方法相當多<br/>
我已經很盡量的複寫大部分的方法了<br/>
</p>
<p>
TextWrapper Class:
</p>
<pre name="code" class="as3:showcolumns:contentHeight[400px]">
/*
TextWrapper AS3 v0.0.2
Date: 2007.04.25
作者: Ticore Shih
Blog:http://ticore.blogspot.com
EMail: swl@ms53.url.com.tw
v0.0.1
繼承 Sprite 包覆一個 TextField
v0.0.2
增加 TextField 一般性方法
*/
package com.ticore.text {
import flash.geom.*;
import flash.display.*;
import flash.text.*;
import flash.events.*;
public class TextWrapper extends Sprite {
//
// Protected Property
//
protected var _txt_:TextField;
//
// Constructor
//
public function TextWrapper() {
init();
}
protected function init():void {
_txt_ = new TextField();
this.addChild(_txt_);
}
//
// Override DisplayObject Property and Method
//
public override function set width(w:Number):void {
_txt_.width = w;
}
public override function get width():Number {
return _txt_.width;
}
public override function set height(h:Number):void {
_txt_.height = h;
}
public override function get height():Number {
return _txt_.height;
}
//
// Proxy Common TextField Property
//
public function set antiAliasType(value:String):void {
_txt_.antiAliasType = value;
}
public function get antiAliasType():String {
return _txt_.antiAliasType;
}
public function set autoSize(value:String):void {
_txt_.autoSize = value;
}
public function get autoSize():String {
return _txt_.autoSize;
}
public function set gridFitType(value:String):void {
_txt_.gridFitType = value;
}
public function get gridFitType():String {
return _txt_.gridFitType;
}
public function set htmlText(value:String):void {
_txt_.htmlText = value;
}
public function get htmlText():String {
return _txt_.htmlText;
}
public function set restrict(value:String):void {
_txt_.restrict = value;
}
public function get restrict():String {
return _txt_.restrict;
}
public function set text(txt:String):void {
_txt_.text = txt;
}
public function get text():String {
return _txt_.text;
}
public function set type(type:String):void {
_txt_.type = type;
}
public function get type():String {
return _txt_.type;
}
public function set backgroundColor(value:uint):void {
_txt_.backgroundColor = value;
}
public function get backgroundColor():uint {
return _txt_.backgroundColor;
}
public function set borderColor(value:uint):void {
_txt_.borderColor = value;
}
public function get borderColor():uint {
return _txt_.borderColor;
}
public function set textColor(value:uint):void {
_txt_.textColor = value;
}
public function get textColor():uint {
return _txt_.textColor;
}
public function get bottomScrollV():int {
return _txt_.bottomScrollV;
}
public function get caretIndex():int {
return _txt_.caretIndex;
}
public function get length():int {
return _txt_.length;
}
public function get maxChars():int {
return _txt_.maxChars;
}
public function get maxScrollH():int {
return _txt_.maxScrollH;
}
public function get maxScrollV():int {
return _txt_.maxScrollV;
}
public function get numLines():int {
return _txt_.numLines;
}
public function get selectionBeginIndex():int {
return _txt_.selectionBeginIndex;
}
public function get selectionEndIndex():int {
return _txt_.selectionEndIndex;
}
public function set sharpness(value:Number):void {
_txt_.sharpness = value;
}
public function get sharpness():Number {
return _txt_.sharpness;
}
public function set thickness(value:Number):void {
_txt_.thickness = value;
}
public function get thickness():Number {
return _txt_.thickness;
}
public function get textHeight():Number {
return _txt_.textHeight;
}
public function get textWidth():Number {
return _txt_.textWidth;
}
public function set alwaysShowSelection(value:Boolean):void {
_txt_.alwaysShowSelection = value;
}
public function get alwaysShowSelection():Boolean {
return _txt_.alwaysShowSelection;
}
public function set border(value:Boolean):void {
_txt_.border = value;
}
public function get border():Boolean {
return _txt_.border;
}
public function set condenseWhite(value:Boolean):void {
_txt_.condenseWhite = value;
}
public function get condenseWhite():Boolean {
return _txt_.condenseWhite;
}
public function set displayAsPassword(value:Boolean):void {
_txt_.displayAsPassword = value;
}
public function get displayAsPassword():Boolean {
return _txt_.displayAsPassword;
}
public function set embedFonts(value:Boolean):void {
_txt_.embedFonts = value;
}
public function get embedFonts():Boolean {
return _txt_.embedFonts;
}
public function set mouseWheelEnabled(value:Boolean):void {
_txt_.mouseWheelEnabled = value;
}
public function get mouseWheelEnabled():Boolean {
return _txt_.mouseWheelEnabled;
}
public function set multiline(value:Boolean):void {
_txt_.multiline = value;
}
public function get multiline():Boolean {
return _txt_.multiline;
}
public function set selectable(value:Boolean):void {
_txt_.selectable = value;
}
public function get selectable():Boolean {
return _txt_.selectable;
}
public function set useRichTextClipboard(value:Boolean):void {
_txt_.useRichTextClipboard = value;
}
public function get useRichTextClipboard():Boolean {
return _txt_.useRichTextClipboard;
}
public function set wordWrap(value:Boolean):void {
_txt_.wordWrap = value;
}
public function get wordWrap():Boolean {
return _txt_.wordWrap;
}
//
// Proxy Common TextField Method
//
public function appendText(text:String):void {
_txt_.appendText(text);
}
public function getCharBoundaries(charIndex:int):Rectangle {
return _txt_.getCharBoundaries(charIndex);
}
public function getCharIndexAtPoint(x:Number, y:Number):int {
return _txt_.getCharIndexAtPoint(x,y);
}
public function getFirstCharInParagraph(charIndex:int):int {
return _txt_.getFirstCharInParagraph(charIndex);
}
public function getImageReference(id:String):DisplayObject {
return _txt_.getImageReference(id);
}
public function getLineIndexAtPoint(x:Number, y:Number):int {
return _txt_.getLineIndexAtPoint(x,y);
}
public function getLineIndexOfChar(charIndex:int):int {
return _txt_.getLineIndexOfChar(charIndex);
}
public function getLineLength(lineIndex:int):int {
return _txt_.getLineLength(lineIndex);
}
public function getLineMetrics(lineIndex:int):TextLineMetrics {
return _txt_.getLineMetrics(lineIndex);
}
public function getLineOffset(lineIndex:int):int {
return _txt_.getLineOffset(lineIndex);
}
public function getLineText(lineIndex:int):String {
return _txt_.getLineText(lineIndex);
}
public function getParagraphLength(charIndex:int):int {
return _txt_.getParagraphLength(charIndex);
}
public function replaceSelectedText(value:String):void {
_txt_.replaceSelectedText(value);
}
public function replaceText(beginIndex:int, endIndex:int, newText:String):void {
_txt_.replaceText(beginIndex,endIndex,newText);
}
public function setTextFormat(format:TextFormat, beginIndex:int = -1, endIndex:int = -1):void {
_txt_.setTextFormat(format,beginIndex,endIndex);
}
public function getTextFormat(beginIndex:int = -1, endIndex:int = -1):TextFormat {
return _txt_.getTextFormat(beginIndex,endIndex);
}
public function set defaultTextFormat(format:TextFormat):void {
_txt_.defaultTextFormat = format;
}
public function get defaultTextFormat():TextFormat {
return _txt_.defaultTextFormat;
}
}
}
</pre>
<p>
BitmapText Class:
</p>
<pre name="code" class="as3:showcolumns:contentHeight[400px]">
/*
BitmapText AS3 v0.0.4
Date: 2007.04.25
作者: Ticore Shih
Blog:http://ticore.blogspot.com
EMail: swl@ms53.url.com.tw
v0.0.1
利用 BitmapData draw TextFIeld
達到可以呈現旋轉文字的效果
v0.0.2
增加 TextField 一般性方法與屬性控制
增加 validate 屬性,減少不必要 draw 次數
TextField.autoSize 功能會有一些問題
TextField 大小會一直跳動,重複 draw 會發生多重影像
v0.0.3
增加 TextField 一般性方法與屬性控制
v0.0.4
重構將 TextWrapper 功能獨立為單一 Class
*/
package com.ticore.text {
import flash.geom.*;
import flash.display.*;
import flash.text.*;
import flash.events.*;
import flash.filters.*;
public class BitmapText extends TextWrapper {
// Private Property
private var _validate_:Boolean = true;
private var magniFactor:Number = 3;
private var blurFilter:BlurFilter;
private var _useBitmapText_:Boolean = true;
private var bmpData:BitmapData;
private var bmp:Bitmap;
public function BitmapText() {
init();
}
protected override function init():void {
super.init();
_txt_.addEventListener(Event.CHANGE, onChange);
bmp = new Bitmap();
bmp.smoothing = true;
bmp.scaleX = bmp.scaleY = 1 / magniFactor;
this.addChild(bmp);
_txt_.visible = false;
this.addChild(_txt_);
blurFilter = new BlurFilter(1 + magniFactor / 6, 1 + magniFactor / 6, BitmapFilterQuality.MEDIUM);
validate = false;
addEventListener(Event.ENTER_FRAME, onEnterFame);
}
//
// Private Method
//
private function updateBmpData():void {
if (bmpData) {
bmpData.dispose();
}
bmpData = new BitmapData((width + 1) * magniFactor, (height + 1) * magniFactor, true, 0x00000000);
bmp.bitmapData = bmpData;
bmp.smoothing = true;
validate = false;
}
private function onChange(eventObj:Event):void {
validate = false;
}
private function onEnterFame(eventObj:Event):void {
if (!validate) {
draw();
}
}
private function draw():void {
if (bmpData == null) {
updateBmpData();
}
if (bmpData.width < (width + 1) * magniFactor || bmpData.height < (height + 1) * magniFactor) {
updateBmpData();
}
var rect:Rectangle = new Rectangle(_txt_.x, _txt_.y, _txt_.width, _txt_.height);
bmpData.fillRect(bmpData.rect, 0x00000000);
var xOffset:Number = -_txt_.x;
var dev:Number = magniFactor / 3;
bmpData.draw(_txt_, new Matrix(magniFactor, 0, 0, magniFactor, xOffset * magniFactor + 0, 0));
bmpData.draw(_txt_, new Matrix(magniFactor, 0, 0, magniFactor, xOffset * magniFactor + dev, 0));
bmpData.draw(_txt_, new Matrix(magniFactor, 0, 0, magniFactor, xOffset * magniFactor + 0, dev));
bmpData.applyFilter(bmpData, bmpData.rect, new Point(0, 0), blurFilter);
bmpData.draw(_txt_, new Matrix(magniFactor, 0, 0, magniFactor, xOffset * magniFactor + dev / 2, dev / 2));
bmp.x = _txt_.x;
bmp.y = _txt_.y;
validate = true;
}
//
// Public Method
//
public function set validate(value:Boolean):void {
_validate_ = value;
}
public function get validate():Boolean {
return _validate_;
}
public function set useBitmapText(value:Boolean):void {
_useBitmapText_ = value;
_txt_.visible = !value;
bmp.visible = value;
}
public function get useBitmapText():Boolean {
return _useBitmapText_;
}
//
// Override Method
//
public override function set width(w:Number):void {
super.width = w;
validate = false;
}
public override function set height(h:Number):void {
super.height = h;
validate = false;
}
public override function appendText(text:String):void {
super.appendText(text);
validate = false;
}
public override function replaceSelectedText(value:String):void {
super.replaceSelectedText(value);
validate = false;
}
public override function replaceText(beginIndex:int, endIndex:int, newText:String):void {
super.replaceText(beginIndex,endIndex,newText);
validate = false;
}
public override function setTextFormat(format:TextFormat, beginIndex:int = -1, endIndex:int = -1):void {
super.setTextFormat(format,beginIndex,endIndex);
validate = false;
}
public override function set defaultTextFormat(format:TextFormat):void {
super.defaultTextFormat = format;
validate = false;
}
public override function set antiAliasType(value:String):void {
super.antiAliasType = value;
validate = false;
}
public override function set autoSize(value:String):void {
super.autoSize = value;
validate = false;
}
public override function set gridFitType(value:String):void {
super.gridFitType = value;
validate = false;
}
public override function set htmlText(value:String):void {
super.htmlText = value;
validate = false;
}
public override function set restrict(value:String):void {
super.restrict = value;
validate = false;
}
public override function set text(value:String):void {
super.text = value;
validate = false;
}
public override function set backgroundColor(value:uint):void {
super.backgroundColor = value;
validate = false;
}
public override function set borderColor(value:uint):void {
super.borderColor = value;
validate = false;
}
public override function set textColor(value:uint):void {
super.textColor = value;
validate = false;
}
public override function set sharpness(value:Number):void {
super.sharpness = value;
validate = false;
}
public override function set thickness(value:Number):void {
super.thickness = value;
validate = false;
}
public override function set alwaysShowSelection(value:Boolean):void {
super.alwaysShowSelection = value;
validate = false;
}
public override function set border(value:Boolean):void {
super.border = value;
validate = false;
}
public override function set condenseWhite(value:Boolean):void {
super.condenseWhite = value;
validate = false;
}
public override function set displayAsPassword(value:Boolean):void {
super.displayAsPassword = value;
validate = false;
}
public override function set embedFonts(value:Boolean):void {
super.embedFonts = value;
validate = false;
}
public override function set multiline(value:Boolean):void {
super.multiline = value;
validate = false;
}
public override function set selectable(value:Boolean):void {
super.selectable = value;
validate = false;
}
public override function set wordWrap(value:Boolean):void {
super.wordWrap = value;
validate = false;
}
}
}
</pre>
<p>
測試程式如下:
</p>
<pre name="code" class="as3:showcolumns">
import com.ticore.text.*;
var bmpTxt:BitmapText = new BitmapText();
this.addChild(bmpTxt);
bmpTxt.border = true;
bmpTxt.multiline = true;
bmpTxt.rotation = 0;
bmpTxt.wordWrap = true;
bmpTxt.rotation = 15;
bmpTxt.width = 320;
bmpTxt.height = 250;
bmpTxt.x = 170;
bmpTxt.y = 30;
var format:TextFormat = bmpTxt.getTextFormat();
format.font = "新細明體";
format.align = "center";
for (var i:Number = 6; i <= 22; ++i) {
format.size = i;
bmpTxt.defaultTextFormat = format;
bmpTxt.appendText("Font Size " + format.size + " 新細明體\n");
}
</pre>
<p>
<a href="http://riafiles.googlepages.com/BitmapText_0.0.5.zip">原始檔案下載</a>
</p>
<p>
實際執行效果擷圖:
</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_JHhe1vma7nY/SG9pUTEQDJI/AAAAAAAAAbA/pjOWlfY-sLE/s1600-h/BitmapTextDemo.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_JHhe1vma7nY/SG9pUTEQDJI/AAAAAAAAAbA/pjOWlfY-sLE/s320/BitmapTextDemo.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5219506290582097042" /></a>
<p>
看起來應該還不錯吧!<br/>
即使在旋轉狀態下也沒有很嚴重的鋸齒<br/>
我特別在繪製點陣圖步驟提升了解析度<br/>
並且作了偏移繪製,套用濾鏡<br/>
當然這些動作是會消耗效能的<br/>
所以只有在必要時才會進行重繪的動作
</p>
</span>{id: "Ticore"}; //http://www.blogger.com/profile/01433005931305983346noreply@blogger.comtag:blogger.com,1999:blog-6934949377658966040.post-86497411775306354632007-10-06T16:46:00.000+08:002008-07-14T18:17:47.988+08:002008-07-14T18:17:47.988+08:00在 Flash 作點陣圖九宮格縮放技巧<p align="right" class="author"><a href="http://ticore.blogspot.com/">Ticore's Blog</a></p>
<p>
Flash 8、9 雖然有支援 Scale 9 縮放功能<br/>
但是僅限於向量物件<br/>
MovieClip 的 Scale 9 設定對點陣圖並沒有效果<br/>
以下介紹一個技巧,可以讓 Flash Scale 9 功能也能應用在點陣圖上
</p>
<span class="fullpost">
<p>先將點陣圖包成 MovieClip,並勾選 Scale 9 設定</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_JHhe1vma7nY/RwdM_lB1aRI/AAAAAAAAARc/hKOxo1e01rY/s1600-h/Bitmap_Scale9_Step1.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_JHhe1vma7nY/RwdM_lB1aRI/AAAAAAAAARc/hKOxo1e01rY/s320/Bitmap_Scale9_Step1.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5118144156685134098" /></a>
<p>將點陣圖打散成為向量填色區塊</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_JHhe1vma7nY/RwdNPFB1aSI/AAAAAAAAARk/6B-uLoDSPkQ/s1600-h/Bitmap_Scale9_Step2.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_JHhe1vma7nY/RwdNPFB1aSI/AAAAAAAAARk/6B-uLoDSPkQ/s320/Bitmap_Scale9_Step2.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5118144422973106466" /></a>
<p>沿著 Scale 9 Grid 劃線,將點陣圖填色區塊切割開</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_JHhe1vma7nY/RwdNWVB1aTI/AAAAAAAAARs/KZ9Q-XpVhwA/s1600-h/Bitmap_Scale9_Step3.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_JHhe1vma7nY/RwdNWVB1aTI/AAAAAAAAARs/KZ9Q-XpVhwA/s320/Bitmap_Scale9_Step3.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5118144547527158066" /></a>
<p>
最後,把九個填色區塊個別包成群組,刪除切割用的線條<br/>
這樣該 MovieClip 便可以用 Scale 9 模式縮放了
</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp0.blogger.com/_JHhe1vma7nY/RwdNplB1aUI/AAAAAAAAAR0/oDhVYM9W_uk/s1600-h/Bitmap_Scale9_Step4.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp0.blogger.com/_JHhe1vma7nY/RwdNplB1aUI/AAAAAAAAAR0/oDhVYM9W_uk/s320/Bitmap_Scale9_Step4.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5118144878239639874" /></a>
<p>Flash 點陣圖九宮格 (Scale 9) 縮放比較</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_JHhe1vma7nY/RwdOEVB1aVI/AAAAAAAAAR8/wvfqxRIwGYo/s1600-h/Bitmap_Scale9_Compare.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_JHhe1vma7nY/RwdOEVB1aVI/AAAAAAAAAR8/wvfqxRIwGYo/s320/Bitmap_Scale9_Compare.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5118145337801140562" /></a>
<p>
相關連結:<br/>
<a href="http://ticore.blogspot.com/2007/10/flex-embed.html">Flex Embed 點陣圖檔小技巧</a><br/>
<a href="http://ticore.blogspot.com/2007/10/flash-flex-skin.html">用 Flash 開發 Flex Skin 才是王道</a>
</p>
</span>{id: "Ticore"}; //http://www.blogger.com/profile/01433005931305983346noreply@blogger.comtag:blogger.com,1999:blog-6934949377658966040.post-19720567100811263962007-10-06T14:43:00.000+08:002008-07-14T18:17:47.990+08:002008-07-14T18:17:47.990+08:00Flex Embed 點陣圖檔小技巧<p align="right" class="author"><a href="http://ticore.blogspot.com/">Ticore's Blog</a></p>
<p>
Flex 可以使用 Embed 標籤,指定外部圖檔素材<br/>
但是透過這種方式匯入的圖片預設是無抗鋸齒效果的<br/>
雖然可以自行用 AS3 重新以 smooth 方式 draw<br/>
不過實在太麻煩<br/>
</p>
<span class="fullpost">
<p>先看看直接 Embed 圖檔的情況,有很嚴重的鋸齒<p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_JHhe1vma7nY/RwczxVB1aQI/AAAAAAAAARU/zggJp5lAnLQ/s1600-h/NoSmoothing.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_JHhe1vma7nY/RwczxVB1aQI/AAAAAAAAARU/zggJp5lAnLQ/s320/NoSmoothing.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5118116424081303810" /></a>
<p>以下介紹利用 Flash 改善點陣圖鋸齒</p>
<p>將圖檔匯入 Flash,並且勾選 Allow smoothing 選項</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp3.blogger.com/_JHhe1vma7nY/RwcyeVB1aOI/AAAAAAAAARE/othZq9DkDPI/s1600-h/AllowSmoothing.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp3.blogger.com/_JHhe1vma7nY/RwcyeVB1aOI/AAAAAAAAARE/othZq9DkDPI/s320/AllowSmoothing.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5118114998152161506" /></a>
<p>
將圖片包成一個 MovieClip,並輸出 SWF<br/>
在 Flex MXML 內指定 Embed 標籤
</p>
<pre name="code" class="mxml">
<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"
width="120" height="112"
backgroundImage="@Embed(source='assets.swf', symbol='fx')">
</mx:Application>
</pre>
<p>執行結果</p>
<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_JHhe1vma7nY/RwczhFB1aPI/AAAAAAAAARM/qHnVKYe8Vwk/s1600-h/Smoothing.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_JHhe1vma7nY/RwczhFB1aPI/AAAAAAAAARM/qHnVKYe8Vwk/s320/Smoothing.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5118116144908429554" /></a>
<p>
相關連結:<br/>
<a href="http://ticore.blogspot.com/2007/10/flash-flex-skin.html">用 Flash 開發 Flex Skin 才是王道</a><br/>
<a href="http://ticore.blogspot.com/2007/10/flash-bitmap-scale-9-tip.html">在 Flash 作點陣圖九宮格縮放技巧</a><br/>
<a href="http://ticore.blogspot.com/2007/11/flex-embed-assets-skill.html">Flex Embed 外部資源技巧</a>
</p>
</span>{id: "Ticore"}; //http://www.blogger.com/profile/01433005931305983346noreply@blogger.comtag:blogger.com,1999:blog-6934949377658966040.post-38303722734010413422007-01-21T13:25:00.001+08:002008-07-14T18:14:18.860+08:002008-07-14T18:14:18.860+08:00ActionScript BitmapData.draw TextField Bug<p align="right" class="author"><a href="http://ticore.blogspot.com/">Ticore's Blog</a></p>
<p><strong>問題描述:</strong></p>
<p>使用 BitmapData.draw 繪制 TextField 點陣圖資料<br />
該 TextField 使用非嵌入字體<br />
且 draw 方法的 blendMode 參數非為 "normal"</p>
<p>同時使用者用滑鼠拖動應用程式視窗<br />
或是打開應用程式控制選單(application control menu)<br />
或是調整視窗大小<br />
會造成該 Flash Movie 所在執行應用程式 (Flash Player、Browser、Flash IDE)<br />
執行發生錯誤而終止</p>
<span class="fullpost">
<p><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="http://bp2.blogger.com/_JHhe1vma7nY/Rml51cqa5jI/AAAAAAAAADQ/2jYEFD3r-q8/s1600-h/0-1.gif"><img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://bp2.blogger.com/_JHhe1vma7nY/Rml51cqa5jI/AAAAAAAAADQ/2jYEFD3r-q8/s320/0-1.gif" border="0" alt=""id="BLOGGER_PHOTO_ID_5073720414343718450" /></a></p>
<p> </p>
<p><strong>執行環境與條件:</strong></p>
<p>ActionScript Version:1、2、3<br />
SWF Version:8、9<br />
Flash Player Version:8、9<br />
Player Mode:StandAlone、Plugin、ActiveX、External<br />
Browser:IE、Firefox<br />
OS:Windows XP SP2 cht
</p>
<p> </p>
<p>ActionScript 2 Bug Demo:</p>
<pre name="code" class="as3">import flash.display.*;
import flash.geom.*;
var root:MovieClip = this;
var txt:TextField = root.createTextField("txt", root.getNextHighestDepth(), 100, 50, 100, 100);
var bmp:BitmapData = new BitmapData(txt._width, txt._height, true, 0);
root.attachBitmap(bmp, root.getNextHighestDepth());
root.onEnterFrame = function() {
bmp.draw(txt, new Matrix(1, 0, 0, 1), null, "add");
}; </pre>
<p>ActionScript 3 Bug Demo:</p>
<pre name="code" class="as3">package {
import flash.display.*;
import flash.text.*;
import flash.utils.*;
import flash.geom.*;
public class Main extends MovieClip {
public var txt:TextField;
public var bmp:BitmapData;
public function Main () {
txt = new TextField();
txt.x = 100;
txt.y = 50;
txt.width = 100;
txt.height = 100;
bmp = new BitmapData(txt.width, txt.height, true, 0);
setInterval(doDraw, 100);
}
public function doDraw () {
bmp.draw(txt, new Matrix(1, 0, 0, 1), null, "add");
}
}
}</pre>
<p>
該 Bug 在以下版本 Windows Flash Player 測試會發生<br/>
Flash Player 9.0.15.0<br/>
Flash Player 9.0.16.0<br/>
Flash Player 9.0.28.0<br/>
Flash Player 9.0.45.0<br/>
Flash Player 9.0.47.0<br/>
Flash Player 9.0.60.120<br/>
Flash Player 9.0.60.235<br/>
Flash Player 9.0.64.0<br/>
Flash Player 9.0.115.0<br/>
Flash Player 9.0.124.0
</p>
<p>
相關連結:<br/>
<a href="http://ticore.blogspot.com/2007/12/as3-textfield-render-bug.html">Flash Player TextField Render Bug</a>
</p>
</span>{id: "Ticore"}; //http://www.blogger.com/profile/01433005931305983346noreply@blogger.comtag:blogger.com,1999:blog-6934949377658966040.post-31799423183867422472006-11-09T13:42:00.002+08:002008-07-14T18:14:18.863+08:002008-07-14T18:14:18.863+08:00動態讀取外部 PNG 作為 Alpha Mask<p align="right" class="author"><a href="http://ticore.blogspot.com/">Ticore's Blog</a></p>
<p>
看到邦邦的問題<br/>
<a href="http://mmug.com.tw/forum/viewtopic.php?p=39227">http://mmug.com.tw/forum/viewtopic.php?p=39227</a><br /><br />
測試出來的結果如下:
</p>
<span class="fullpost">
<hr />
<object width="100%" height="200" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=8,0,0,0" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000">
<param value="http://riafiles.googlepages.com/gradientMask.swf" name="movie" />
<param value="high" name="quality" />
<param value="maskURL=http://riafiles.googlepages.com/gradientMask.png" name="flashvars" />
<embed width="100%" height="200" flashvars="maskURL=http://riafiles.googlepages.com/gradientMask.png" type="application/x-shockwave-flash" pluginspage="http://www.macromedia.com/go/getflashplayer" quality="high" src="http://riafiles.googlepages.com/gradientMask.swf"></embed>
</object>
<hr />
<p>
SWF URL:<br />
<a href="http://riafiles.googlepages.com/gradientMask.swf">http://riafiles.googlepages.com/gradientMask.swf</a><br /><br />
PNG URL:<br />
<a href="http://riafiles.googlepages.com/gradientMask.png">http://riafiles.googlepages.com/gradientMask.png</a>
</p>
<p>
關鍵應該是在設定 mask.cacheAsBitmap 的時機
</p>
<p>ActionScript:</p>
<pre name="code" class="as3:showcolumns">
var maskURL:String = maskURL == null ? "gradientMask.png" : maskURL;
import flash.geom.*;
var maskee:MovieClip = this.createEmptyMovieClip("maskee", 100);
var masker:MovieClip = this.createEmptyMovieClip("masker", 200);
with (maskee) {
colors = [0xFF0000, 0x0000FF];
fillType = "radial"
alphas = [100, 100];
ratios = [0, 0xFF];
spreadMethod = "reflect";
interpolationMethod = "linearRGB";
focalPointRatio = 0.9;
matrix = new Matrix();
matrix.createGradientBox(100, 100, Math.PI, 0, 0);
beginGradientFill(fillType, colors, alphas, ratios, matrix,
spreadMethod, interpolationMethod, focalPointRatio);
moveTo(0, 0);
lineTo(550, 0);
lineTo(550, 200);
lineTo(0, 200);
lineTo(0, 0);
endFill();
}
var mcLoader:MovieClipLoader = new MovieClipLoader();
var mcLisObj:Object = {};
mcLisObj.onLoadInit = function(evtObj):Void{
masker.cacheAsBitmap = true;
masker.onPress = function():Void{
startDrag(this);
};
masker.onRelease = masker.onReleaseOutside = function():Void{
stopDrag();
};
maskee.cacheAsBitmap = true;
maskee.setMask(masker);
};
mcLoader.addListener(mcLisObj);
mcLoader.loadClip(maskURL, masker);
// Ticore's Blog - http://ticore.blogspot.com/
</pre>
</span>{id: "Ticore"}; //http://www.blogger.com/profile/01433005931305983346noreply@blogger.comtag:blogger.com,1999:blog-6934949377658966040.post-83763062390508038632005-09-26T23:12:00.001+08:002008-07-14T18:14:18.779+08:002008-07-14T18:14:18.779+08:00Flash 8 AS2 數字進位轉換 Bug<p align="right" class="author"><a href="http://ticore.blogspot.com/">Ticore's Blog</a></p>
<p>
由於新功能 BitmapData 出現<br />
最近嘗試使用它來做一些資料轉換<br />
常常用到 getPixel32<br />
為了減少資料長度<br />
把它轉成 16 或是 32 進位<br />
一旦來源數字大小超過 0x80000000<br />
轉換就會出現奇怪的字元
</p>
<span class="fullpost">
<p>居然會出現以下的結果:</p>
<pre name="code" class="as3:showcolumns">
/*
Ticore's Blog
http://ticore.blogspot.com/
*/
trace(0x80000000.toString(16));
trace(0x80000000.toString(32));
trace(0x80000001.toString(16));
trace(0x80000001.toString(32));
// output:
// -(0000000
// -.000000
// -7fffffff
// -1vvvvvv</pre>
<p>
以前的版本好像也有一樣的狀況<br />
只不過以前很少需要用到 32bit 整數轉換吧<br />
javascript 與 actionscript 是很類似的東西<br />
為什麼 javascript 就可以出現正確的結果~
</p>
<p>
相關連結:<a href="http://ticore.blogspot.com/2005/09/as2-numbertostring.html">覆寫 AS2 Number.toString() 函式</a>
<p>
</span>{id: "Ticore"}; //http://www.blogger.com/profile/01433005931305983346noreply@blogger.comtag:blogger.com,1999:blog-6934949377658966040.post-28720611969219893602005-09-21T20:05:00.001+08:002008-07-14T18:14:18.923+08:002008-07-14T18:14:18.923+08:00Flash 8 AS2 點陣圖雙線性取樣函式<p align="right" class="author"><a href="http://ticore.blogspot.com/">Ticore's Blog</a></p>
<p>
既然 Flash 8 可以直接操作點陣資料<br />
那就可以用來實作一些影像處理的功能了<br />
以下便是用 AS 作點陣圖雙線性重新取樣函式
</p>
<span class="fullpost">
<p>
不過這只是個人研究用的<br />
畢竟AS跑大量迴圈還是比不上 Native 程式<br />
所以並不具有實用的價值
</p>
<p>
真正欲做點陣圖縮放,可以使用 Matrix + draw<br />
至少比 AS Implement 的快上100倍
</p>
<pre>
/*
Ticore's Blog
http://ticore.blogspot.com/
*/
<font color="#0000ff">import flash.display.*;</font>
<font color="#0000ff">import flash.geom.*;</font>
//=======================================================================
<font color="#0000ff">function</font> resizeTo(<font color="#0000ff">width</font>:<font color="#0000ff">Number</font>, <font color="#0000ff">height</font>:<font color="#0000ff">Number</font>, img:<font color="#0000ff">BitmapData</font>):<font color="#0000ff">BitmapData</font> {<br /> <font color="#0000ff">var</font> temp:<font color="#0000ff">BitmapData</font> = <font color="#0000ff">new</font> <font color="#0000ff">BitmapData</font>(<font color="#0000ff">width</font>, <font color="#0000ff">height</font>, true, 0xFF000000);<br /> <br /> <font color="#0000ff">var</font> p0:<font color="#0000ff">Point</font> = <font color="#0000ff">new</font> <font color="#0000ff">Point</font>();<br /> <font color="#0000ff">var</font> p1:<font color="#0000ff">Point</font> = <font color="#0000ff">new</font> <font color="#0000ff">Point</font>();<br /> <font color="#0000ff">var</font> p2:<font color="#0000ff">Point</font> = <font color="#0000ff">new</font> <font color="#0000ff">Point</font>();<br /> <font color="#0000ff">var</font> p3:<font color="#0000ff">Point</font> = <font color="#0000ff">new</font> <font color="#0000ff">Point</font>();<br /> <font color="#0000ff">var</font> p4:<font color="#0000ff">Point</font> = <font color="#0000ff">new</font> <font color="#0000ff">Point</font>();<br /> <br /> <font color="#0000ff">var</font> c1:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> c2:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> c3:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> c4:<font color="#0000ff">Number</font>;<br /> <br /> <font color="#0000ff">var</font> a:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> r:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> g:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> b:<font color="#0000ff">Number</font>;<br /> <br /> <font color="#0000ff">var</font> dx:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> dy:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> cdx:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> cdy:<font color="#0000ff">Number</font>;<br /> <br /> <font color="#0000ff">var</font> dtl:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> dtr:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> dbl:<font color="#0000ff">Number</font>;<br /> <font color="#0000ff">var</font> dbr:<font color="#0000ff">Number</font>;<br /> <br /> for(<font color="#0000ff">var</font> i:<font color="#0000ff">Number</font> = 0 ; i < <font color="#0000ff">width</font> ; ++i){<br /> for(<font color="#0000ff">var</font> j:<font color="#0000ff">Number</font> = 0 ; j < <font color="#0000ff">height</font> ; ++j){<br /> p0.x = i / <font color="#0000ff">width</font> * (img.<font color="#0000ff">width</font> -1);<br /> p0.y = j / <font color="#0000ff">height</font> * (img.<font color="#0000ff">height</font> - 1);<br /> p1.x = <font color="#0000ff">Math.floor</font>(p0.x);<br /> p1.y = <font color="#0000ff">Math.floor</font>(p0.y);<br /> p2.x = p1.x + 1;<br /> p2.y = p1.y;<br /> p3.x = p1.x + 1;<br /> p3.y = p1.y + 1;<br /> p4.x = p1.x;<br /> p4.y = p1.y + 1;<br /> <br /> c1 = img.<font color="#0000ff">getPixel32</font>(p1.x, p1.y);<br /> c2 = img.<font color="#0000ff">getPixel32</font>(p2.x, p2.y);<br /> c3 = img.<font color="#0000ff">getPixel32</font>(p3.x, p3.y);<br /> c4 = img.<font color="#0000ff">getPixel32</font>(p4.x, p4.y);<br /> <br /> dx = p0.x - p1.x;<br /> dy = p0.y - p1.y;<br /> cdx = 1 - dx;<br /> cdy = 1 - dy;<br /> <br /> dtl = dx * dy;<br /> dtr = cdx * dy;<br /> dbr = dx * cdy;<br /> dbl = cdx * cdy;<br /> <br /> a = ((c1 & 0xFF000000) * dbl<br /> + (c2 & 0xFF000000) * dbr<br /> + (c3 & 0xFF000000) * dtl<br /> + (c4 & 0xFF000000) * dtr) & 0xFF000000;<br /> <br /> r = ((c1 & 0x00FF0000) * dbl<br /> + (c2 & 0x00FF0000) * dbr<br /> + (c3 & 0x00FF0000) * dtl<br /> + (c4 & 0x00FF0000) * dtr) & 0x00FF0000;<br /> <br /> g = ((c1 & 0x0000FF00) * dbl<br /> + (c2 & 0x0000FF00) * dbr<br /> + (c3 & 0x0000FF00) * dtl<br /> + (c4 & 0x0000FF00) * dtr) & 0x0000FF00;<br /> <br /> b = ((c1 & 0x000000FF) * dbl<br /> + (c2 & 0x000000FF) * dbr<br /> + (c3 & 0x000000FF) * dtl<br /> + (c4 & 0x000000FF) * dtr) & 0x000000FF;<br /> <br /> temp.<font color="#0000ff">setPixel32</font>(i , j , a | r | g | b);<br /> }<br /> }<br /> <font color="#0000ff">return</font> temp;<br />}<br /><br />//=======================================================================
</pre>
</span>{id: "Ticore"}; //http://www.blogger.com/profile/01433005931305983346noreply@blogger.comtag:blogger.com,1999:blog-6934949377658966040.post-81801626859306419962005-09-07T10:43:00.000+08:002007-10-31T22:51:37.523+08:002007-10-31T22:51:37.523+08:00Hotspot Demo Video 2<p align="right" class="author"><a href="http://ticore.blogspot.com/">Ticore's Blog</a></p>
這是利用Flash 8新功能BitmapData處理功能加上WebCam作出來的<br />
<br />利用雷射筆光源的開啟、關閉、移動<br />
觸發事件<br />
達到互動的效果<br />
<span class="fullpost">
<br />畫面上的三個MovieClip先對Hotspot註冊事件<br />
才能接受Hotspot的事件呼叫<br />進行互動<br /><br />Hotspot分析點陣資料之後<br />計算出雷射筆的位置<br />換算座標<br />最後發布事件<br /><br />
<object width="425" height="350"><param name="movie" value="http://www.youtube.com/v/DVp495oGf4k"></param><param name="wmode" value="transparent"></param><embed src="http://www.youtube.com/v/DVp495oGf4k" type="application/x-shockwave-flash" wmode="transparent" width="425" height="350"></embed></object></span>{id: "Ticore"}; //http://www.blogger.com/profile/01433005931305983346noreply@blogger.com