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 &lt; (width + 1) * magniFactor || bmpData.height &lt; (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"> &lt;?xml version="1.0" encoding="utf-8"?&gt; &lt;mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" width="120" height="112" backgroundImage="@Embed(source='assets.swf', symbol='fx')"&gt; &lt;/mx:Application&gt; </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 參數非為 &quot;normal&quot;</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>&nbsp;</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>&nbsp;</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(&quot;txt&quot;, 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, &quot;add&quot;); }; </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, &quot;add&quot;); } } }</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 &lt; <font color="#0000ff">width</font> ; ++i){<br /> for(<font color="#0000ff">var</font> j:<font color="#0000ff">Number</font> = 0 ; j &lt; <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 &amp; 0xFF000000) * dbl<br /> + (c2 &amp; 0xFF000000) * dbr<br /> + (c3 &amp; 0xFF000000) * dtl<br /> + (c4 &amp; 0xFF000000) * dtr) &amp; 0xFF000000;<br /> <br /> r = ((c1 &amp; 0x00FF0000) * dbl<br /> + (c2 &amp; 0x00FF0000) * dbr<br /> + (c3 &amp; 0x00FF0000) * dtl<br /> + (c4 &amp; 0x00FF0000) * dtr) &amp; 0x00FF0000;<br /> <br /> g = ((c1 &amp; 0x0000FF00) * dbl<br /> + (c2 &amp; 0x0000FF00) * dbr<br /> + (c3 &amp; 0x0000FF00) * dtl<br /> + (c4 &amp; 0x0000FF00) * dtr) &amp; 0x0000FF00;<br /> <br /> b = ((c1 &amp; 0x000000FF) * dbl<br /> + (c2 &amp; 0x000000FF) * dbr<br /> + (c3 &amp; 0x000000FF) * dtl<br /> + (c4 &amp; 0x000000FF) * dtr) &amp; 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