小弟最近有一個案子需要使用到QR Code來進行一些使用者的互動
為了省去一些麻煩,所以還是選用了Flex為開發的平台
一開始在尋找barcode 相關資料時就有發現到原來zxing的library有AS3的版本
優點是Android以及IOS一次通吃
但經我我的實測之後發現效率實在不行,不但不能及時掃描(需要用按鈕去觸發不然會LAG到死),且辨識率也與原生的zxing barcode程式相差甚遠
為了解決辨識率的問題,我開始傾向使用ANE的方式並呼叫原生的zxing barcode程式
一開始找到了
http://www.ubekar.com/project-barcodereaderANE.html
ubekar寫的Barcode Reader ANE
使用起來相當的簡單(比用AS3的zxing還簡單)
但這個ANE經過我的測試之後發現有個致命的缺點,
那就是在我的x10i上面執行後,相機擷取出來的畫面有上下左右相反的問題,
且在橫向模式會有掃描框超出範圍的問題
對此我想除了等到ubekar更新之前應該都別無他法
正當我想要開始著手寫一個zxing的ane時
我在一個中國的論壇找到了另一個ane
同樣也是基於zxing所寫的
http://bbs.9ria.com/thread-106240-1-1.html
沒錯他的連結就只有一個論壇的網址
http://www.littlesix.com.cn/air/android/barcodereader.zip
(↑此連結可以直接下載ANE檔)
在姑且一試的情況下
沒想到居然就這樣被我找到了
在我的x10i上攝影機畫面擷取正確,手機翻轉時也不會有異常發生
不過這個ANE有個問題
就是她只能在AS3文件下使用
在Flex文件下使用會無法抓到他的Event
(不知道是不是因為他的package為default的關係,還請高手多多指教)
為了解決這個問題,
小弟寫了兩個class來進行橋接的動作
以下分享給各位有需要的朋友
-------------------------------------------------------------------------------------------------------
BarcodeBridge.as
package
{
import flash.events.EventDispatcher;
public class BarcodeBridge extends EventDispatcher
{
private var bc:BarCodeReader=new BarCodeReader();
public function BarcodeBridge()
{
bc.addEventListener(BarCodeEvent.DATA_RECEIVED,onDataRec);
}
private function onDataRec(e:BarCodeEvent):void{
var type:String =e.codeType;
var value:String=e.codeValue;
this.dispatchEvent(new BarcodeEventBridge(e.type,e.codeType,e.codeValue));
}
public function startAnalysis():void{
bc.startAnalysis();
}
}
}
-------------------------------------------------------------------------------------------------------
BarcodeEventBridge.as
package
{
public class BarcodeEventBridge extends BarCodeEvent
{
public static const DATA_RECEIVED:String=BarCodeEvent.DATA_RECEIVED;
public function BarcodeEventBridge(arg0:*,arg1:*,arg2:*)
{
super(arg0);
codeType=arg1;
codeValue=arg2;
}
}
}
----------------------------------------------------------------------------------------------------
使用方式基本上跟原本的ANE使用方式一模一樣,記得要在app.xml裡面加入原本ANE所需要的權限跟行為
<?xml version="1.0" encoding="utf-8"?>
<s:View xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
creationComplete="view1_creationCompleteHandler(event)" title="HomeView">
<fx:Script>
<![CDATA[
import mx.events.FlexEvent;
import spark.effects.CallAction;
private var bc:BarcodeBridge=new BarcodeBridge();
protected function view1_creationCompleteHandler(event:FlexEvent):void
{
bc.addEventListener(BarcodeEventBridge.DATA_RECEIVED,onDataRec);
}
protected function startActivity(event:MouseEvent):void
{
bc.startAnalysis();
}
private function onDataRec(e:BarcodeEventBridge):void{
var type:String =e.codeType;
var value:String=e.codeValue;
this.console.appendText(type+" : "+value);
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:Button x="10" y="10" label="call activity" click="startActivity(event)"/>
<s:TextArea id="console" x="13" y="86" width="457" height="667"/>
</s:View>
----------------------------------------------------------------------------------------------------
另外關於ISO的Barcode ANE其實相對來說好找許多
在此也附上相關連結給需要的人參考
http://www.nativext.com/ane-by-os/ios/qr-reader-native-extension/
http://code.google.com/p/qr-zbar-ane/
2012年12月1日 星期六
2012年11月9日 星期五
使用FLASH AS3製作光碟的AutoRun選單程式
最近接了一個案子是要製作一個光碟的AutoRun選單程式
一開始的想法是利用Flash來進行製作
但找了資料後發現新的Flash player版本已經無法直接透過fscommand來開啟外部的檔案
必須寫bat的方式來進行對應
有興趣的人可以參考這篇
http://milkmidi.blogspot.tw/2010/06/flash-fscommand.html
但因為我這個案子裏面包含了許多的檔案連結要開啟
用bat的方式要一個一個去對應實在是有點麻煩
後來找到了ExternalInterface的方法可以呼叫外部的程式
因此有了利用C#嵌入swf檔並透過AS3呼叫C#開啟外部的程式
詳細的方法請參考以下兩篇
http://blog.another-d-mention.ro/programming/communicate-betwen-c-and-an-embeded-flash-application/
http://help.adobe.com/zh_TW/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7cb0.html
我主要是參考Adobe提供的proxy_ExternalInterfaceCall
來擷取AS3傳來的內容
以下取自C#程式碼
private Flash.External.ExternalInterfaceProxy proxy;
public Form1()
{
InitializeComponent();
axShockwaveFlash1.LoadMovie(0, Application.StartupPath.ToString() + "\\air\\list.swf");
proxy = new Flash.External.ExternalInterfaceProxy(axShockwaveFlash1);
proxy.ExternalInterfaceCall += new Flash.External.ExternalInterfaceCallEventHandler(proxy_ExternalInterfaceCall);
}
//--------------中間省略-----------------
private object proxy_ExternalInterfaceCall(object sender, Flash.External.ExternalInterfaceCallEventArgs e)
{
switch (e.FunctionCall.FunctionName)
{
case "setStage":
this.Size= new System.Drawing.Size(Convert.ToInt32(e.FunctionCall.Arguments[0]),Convert.ToInt32(e.FunctionCall.Arguments[1])+25);
axShockwaveFlash1.Size = new System.Drawing.Size(Convert.ToInt32(e.FunctionCall.Arguments[0]), Convert.ToInt32(e.FunctionCall.Arguments[1]));
return null;
case "oenFile":
//此處為開啟外部程式的method
Process.Start(Application.StartupPath.ToString() + (string)e.FunctionCall.Arguments[0].ToString());
return null;
default:
return null;
}
}
而AS3的部分則是使用ExternalInterface這個類別來進行溝通
以下取自AS3
ExternalInterface.addCallback("myFunction", callMe);
function callMe(name:String):String
{
var result:uint=ExternalInterface.call("setStage",720,440);
//呼叫C#的proxy_ExternalInterfaceCall並且傳遞三個字串
return "";
}
aList.addEventListener(Event.CHANGE, showData);
function showData(event:Event) {
trace(event.target.selectedItem.data);
ExternalInterface.call("oenFile",String(event.target.selectedItem.data));
//呼叫C#的proxy_ExternalInterfaceCall並且傳傳遞selected中的data資料(即為檔案路徑)
}
透過以上的方法便可以直接利用AS3告訴C#開啟的路徑
就可以省去一個一個bat的時間
以下附上C#跟AS3的原始檔
http://dl.dropbox.com/u/12533246/CDROOT.rar
其中也包含已經Release的檔案
有需要的朋友可以直接使用
解壓縮後點擊WindowsFormsApplication11.exe即可觀看效果
若要直接使用的話請把做好的swf檔案放到air資料夾中
並且記得在AS檔案開頭中加入
ExternalInterface.addCallback("myFunction", callMe);
function callMe(name:String):String
{
var result:uint=ExternalInterface.call("setStage",720,440);
//720,440為Flash的場景大小
return "";
}
C#才可以知道要建立多大的場景大小
若還有其他問題也歡迎回應詢問
PS
由於C#是.netframework4架構下面的軟體,所以執行的電腦必須有安裝過.netframework4
及flashplayer
為了解決比較舊的電腦可能沒有安裝過.netframework4
我找了另外一套軟體較做AutoPlay Media Studio
AutoPlay Media Studio是一套商業的軟體,有需要的朋友可以自己去網路上搜尋相關的資料
此軟體產生出來的exe檔便無需安裝.netframework
但flashplayer還是必須的
以下附上AutoPlay Media Studio做出來的檔案及原始檔
http://dl.dropbox.com/u/12533246/FlashAPMS.rar
flash原始檔附在CD_Root\AutoPlay\Flash\air當中
但release出來的檔案必須放在CD_Root\AutoPlay\Flash\
其他需要注意的地方為
AS3中 開啟檔案的方式要改為
fscommand(String(event.target.selectedItem.data));
String(event.target.selectedItem.data)表示檔案的相對位置
路徑用\\來表示(例如dir01/011.txt必須設定為dir01\\011.txt)
並且在AutoPlay Media Studio的Flash元件中加入Script
File.Open(e_FSCommand, "", SW_SHOWNORMAL);
有需要的人可以直接下載使用
直接替換掉CD_Root\AutoPlay\Flash\list.swf即可
場景大小必須是720x440
一開始的想法是利用Flash來進行製作
但找了資料後發現新的Flash player版本已經無法直接透過fscommand來開啟外部的檔案
必須寫bat的方式來進行對應
有興趣的人可以參考這篇
http://milkmidi.blogspot.tw/2010/06/flash-fscommand.html
但因為我這個案子裏面包含了許多的檔案連結要開啟
用bat的方式要一個一個去對應實在是有點麻煩
後來找到了ExternalInterface的方法可以呼叫外部的程式
因此有了利用C#嵌入swf檔並透過AS3呼叫C#開啟外部的程式
詳細的方法請參考以下兩篇
http://blog.another-d-mention.ro/programming/communicate-betwen-c-and-an-embeded-flash-application/
http://help.adobe.com/zh_TW/ActionScript/3.0_ProgrammingAS3/WS5b3ccc516d4fbf351e63e3d118a9b90204-7cb0.html
我主要是參考Adobe提供的proxy_ExternalInterfaceCall
來擷取AS3傳來的內容
以下取自C#程式碼
private Flash.External.ExternalInterfaceProxy proxy;
public Form1()
{
InitializeComponent();
axShockwaveFlash1.LoadMovie(0, Application.StartupPath.ToString() + "\\air\\list.swf");
proxy = new Flash.External.ExternalInterfaceProxy(axShockwaveFlash1);
proxy.ExternalInterfaceCall += new Flash.External.ExternalInterfaceCallEventHandler(proxy_ExternalInterfaceCall);
}
//--------------中間省略-----------------
private object proxy_ExternalInterfaceCall(object sender, Flash.External.ExternalInterfaceCallEventArgs e)
{
switch (e.FunctionCall.FunctionName)
{
case "setStage":
this.Size= new System.Drawing.Size(Convert.ToInt32(e.FunctionCall.Arguments[0]),Convert.ToInt32(e.FunctionCall.Arguments[1])+25);
axShockwaveFlash1.Size = new System.Drawing.Size(Convert.ToInt32(e.FunctionCall.Arguments[0]), Convert.ToInt32(e.FunctionCall.Arguments[1]));
return null;
case "oenFile":
//此處為開啟外部程式的method
Process.Start(Application.StartupPath.ToString() + (string)e.FunctionCall.Arguments[0].ToString());
return null;
default:
return null;
}
}
而AS3的部分則是使用ExternalInterface這個類別來進行溝通
以下取自AS3
ExternalInterface.addCallback("myFunction", callMe);
function callMe(name:String):String
{
var result:uint=ExternalInterface.call("setStage",720,440);
//呼叫C#的proxy_ExternalInterfaceCall並且傳遞三個字串
return "";
}
aList.addEventListener(Event.CHANGE, showData);
function showData(event:Event) {
trace(event.target.selectedItem.data);
ExternalInterface.call("oenFile",String(event.target.selectedItem.data));
//呼叫C#的proxy_ExternalInterfaceCall並且傳傳遞selected中的data資料(即為檔案路徑)
}
透過以上的方法便可以直接利用AS3告訴C#開啟的路徑
就可以省去一個一個bat的時間
以下附上C#跟AS3的原始檔
http://dl.dropbox.com/u/12533246/CDROOT.rar
其中也包含已經Release的檔案
有需要的朋友可以直接使用
解壓縮後點擊WindowsFormsApplication11.exe即可觀看效果
若要直接使用的話請把做好的swf檔案放到air資料夾中
並且記得在AS檔案開頭中加入
ExternalInterface.addCallback("myFunction", callMe);
function callMe(name:String):String
{
var result:uint=ExternalInterface.call("setStage",720,440);
//720,440為Flash的場景大小
return "";
}
C#才可以知道要建立多大的場景大小
若還有其他問題也歡迎回應詢問
PS
由於C#是.netframework4架構下面的軟體,所以執行的電腦必須有安裝過.netframework4
及flashplayer
為了解決比較舊的電腦可能沒有安裝過.netframework4
我找了另外一套軟體較做AutoPlay Media Studio
AutoPlay Media Studio是一套商業的軟體,有需要的朋友可以自己去網路上搜尋相關的資料
此軟體產生出來的exe檔便無需安裝.netframework
但flashplayer還是必須的
以下附上AutoPlay Media Studio做出來的檔案及原始檔
http://dl.dropbox.com/u/12533246/FlashAPMS.rar
flash原始檔附在CD_Root\AutoPlay\Flash\air當中
但release出來的檔案必須放在CD_Root\AutoPlay\Flash\
其他需要注意的地方為
AS3中 開啟檔案的方式要改為
fscommand(String(event.target.selectedItem.data));
String(event.target.selectedItem.data)表示檔案的相對位置
路徑用\\來表示(例如dir01/011.txt必須設定為dir01\\011.txt)
並且在AutoPlay Media Studio的Flash元件中加入Script
File.Open(e_FSCommand, "", SW_SHOWNORMAL);
有需要的人可以直接下載使用
直接替換掉CD_Root\AutoPlay\Flash\list.swf即可
場景大小必須是720x440
2012年10月18日 星期四
AS3 Flash產生圖片讓人下載的最佳解法
最近接觸了好幾個案子都要用到AS3產生圖片讓使用者下載
第一個案子是因為本身就要記錄使用者玩玩遊戲後的結果
所以做法是利用AS3 BitmapData類別 產生出要給使用者下載的圖片
使用adobe JPGEncoder將BitmapData編碼成ByteArray格式
再用UploadPostHelpe類別將圖片post給server並傳回圖片的實體連結
這個作法的問題是
假如我不想要server存圖片要怎麼辦??
通常這個問題大家會直接回答用FileReference的dowmload方法讓使用者直接從本地存取圖片
這又衍伸出另外一個問題
就是FileReference的dowmload並不能限定檔案的附檔名格式!!
沒錯!至少Flash10+AS3是不行的!!
這是我找了很多國內外的網頁及資料得到的答案
也就是說我們只能先預設使用者要存的檔案名稱如aaa.jpg
但假如使用者在存檔的時候想要更改檔案名稱如"bbb"但卻不小心把".jpg"刪掉了
那使用者便會存到一個沒有副檔名的檔案
這個問題困擾了我很久
也找了非常多的資料
最後決定還是用post的方法來解決
將檔案post給server但是讓sever在暫存階段就把圖片再傳回user
這樣post回來的圖片瀏覽器就會直接把附檔名鎖起來
就不用擔心檔案會塞爆server的問題了
不過這個方法的缺點是會占用server的下載頻寬,所以還是希望Adobe能趕快解決這個問題..
以下附上AS3 及PHP的原始碼,有需要的人可以參考看看
第一個案子是因為本身就要記錄使用者玩玩遊戲後的結果
所以做法是利用AS3 BitmapData類別 產生出要給使用者下載的圖片
使用adobe JPGEncoder將BitmapData編碼成ByteArray格式
再用UploadPostHelpe類別將圖片post給server並傳回圖片的實體連結
這個作法的問題是
假如我不想要server存圖片要怎麼辦??
通常這個問題大家會直接回答用FileReference的dowmload方法讓使用者直接從本地存取圖片
這又衍伸出另外一個問題
就是FileReference的dowmload並不能限定檔案的附檔名格式!!
沒錯!至少Flash10+AS3是不行的!!
這是我找了很多國內外的網頁及資料得到的答案
也就是說我們只能先預設使用者要存的檔案名稱如aaa.jpg
但假如使用者在存檔的時候想要更改檔案名稱如"bbb"但卻不小心把".jpg"刪掉了
那使用者便會存到一個沒有副檔名的檔案
這個問題困擾了我很久
也找了非常多的資料
最後決定還是用post的方法來解決
將檔案post給server但是讓sever在暫存階段就把圖片再傳回user
這樣post回來的圖片瀏覽器就會直接把附檔名鎖起來
就不用擔心檔案會塞爆server的問題了
不過這個方法的缺點是會占用server的下載頻寬,所以還是希望Adobe能趕快解決這個問題..
以下附上AS3 及PHP的原始碼,有需要的人可以參考看看
2012年8月17日 星期五
[米蘭實習日誌]手機上的Markerless的AR技術(無標籤的擴增實境)
雖然分享會的主題是"有趣的APP"
但我我主要是以Markerless的AR手機技術為主題在做介紹..
首先先介紹什麼事AR的標籤
這是一個很典型的AR標籤,主要的用途就是給AR得載具可以掃描辨識位置
而早期的AR技術都是以電腦加上webCam為主,且辨識得標籤都須有固定的規範,外觀基本上很難脫離某一種樣式,以至於在行銷的使用上有一些先天的限制
但隨著時代的演進
AR的應用不但可以在手機上實現
而且辨識技術越來越先進,可以當作標籤的圖樣也不再受傳統的樣式限制,甚至只要標籤有局部被拍攝到就可以進行辨識
在實作方面
目前最強大的引擎是Obvious Engine AR
他可以實現以非平面的物體進行辨識,這是目前最先進的技術
但相對的這個技術是需要付費的
且在支援度上也只有ios能夠支援
所以市場的接受度並沒有很高
接下來是另一套普比較普及的引擎Qualcomm Vuforia
這是一套高通公司開發的引擎(手機CPU製造商)
他的優點是免費、支援Android及IOS,容易使用上手(15分鐘教你做手機AR)
基本上他開發的軟體是用unity開發,在標籤的支援上也是相當多元
申請開發帳號之後就可以用網路的線上工具將任意的圖檔轉換成標籤的檔案匯入Unity當中
經過測試"米蘭實習生"的招募海報也是有不錯的便是成功率
除了單純得辨識之外Qualcomm Vuforia還具備了一些互動的功能
包括了虛擬的按鈕即一些多物理的互動
最後附上兩個官DEOM影片
沃爾瑪百貨和Super Hero合作的APP
官方的作品集
訂閱:
文章 (Atom)