答案是肯定的。在擴展包MMAPI中,我們可以使用VideoControl加上Player來實現從手機攝像頭捕獲影象數據,並在屏幕上顯示出來。
大家都知道,J2ME的用戶界面總的來說分成兩類,分別是高級界面和低級界面。高級界面使用方便,但自由度不大。低級界面自由度大,但都要靠程序自己來完成。在這兩種界面上VideoControl都可以很好地工作,只需要在初始化時指定對應的工作模式。
函數Object initDisplayMode(int mode, Object arg)用來設置VideoControl的顯示模式,其中參數mode表示顯示的模式,arg則根據mode的取值而變化。目前已有兩種顯示模式被定義,分別是GUIControl.USE_GUI_PRIMITIVE和VideoControl.USE_DIRECT_VIDEO。如果使用USE_GUI_PRIMITIVE,則說明VideoControl將被放置在一個高級界面的容器中顯示出來;相應,使用USE_GUI_PRIMITIVE則說明VideoControl將顯示在低級界面上。
在使用USE_GUI_PRIMITIVE時,參數arg用於指定容器的類型。在僅僅支持一種UI的平台上,如J2ME,僅僅支持LCDUI這一種UI,則可以傳一個null,系統將使用默認的UI;如果在某個支持多種UI(如AWT和LCDUI)的平台中,則需要指定使用何種UI,可以使用一個包含完整類名的字符串來作為參數arg,如"Javax.microedition.lcdui.Item"。相應地,函數initDisplayMode此時返回的Object類型就是參數arg所指定的,或者默認的類型,在J2ME中,是Item。示例如下:
Player p;
VideoControl VC;
try{
p = Manager.createPlayer("capture://video");
p.realize();
vc = (VideoControl) p.getControl("VideoControl");
if (vc != null) {
append((Item)vc.initDisplayMode(VidecControl.USE_GUI_PRIMITIVE, null));//當前類繼承了Form類
}
p.start();
}catch(Exception e){}
模式USE_DIRECT_VIDEO只能被用於LCDUI中,這個時候,參數arg必須是一個Canvas或者它的子類,同時函數將返回null。
Player p;
VideoControl vc;
try{
p = Manager.createPlayer("capture://video");
p.realize();
vc = (VideoControl) p.getControl("VideoControl");
if (vc != null) {
vc.initDisplayMode(VideoControl.USE_DIRECT_VIDEO, this);//當前類繼承了Canvas類
}
vc.setVisible(true);//設置可見
p.start();
}catch(Exception e){}
這兩種模式還有一個很大的區別是,在USE_GUI_PRIMITIVE模式下,默認是可見的,而在USE_DIRECT_VIDEO模式下,默認是不可見的,需要通過方法setVisible(boolean visible)來設置。
無論是哪種模式,我們都可以對畫面的大小進行調整。通過方法setDisplaySize(int width, int height),我們可以設置顯示畫面的大小。這裡注意,是設置顯示畫面的大小,也就是說,它不會影響到後面談到的獲取的快照的大小。在USE_DIRECT_VIDEO模式下,我們還可以設置畫面的位置,方法setDisplayLocation(int x, int y)正是提供了這樣的功能,兩個參數分別是畫面左上角的坐標。而畫面的源大小、顯示大小、顯示位置等信息可以通過VideoControl提供的一些方法來獲取,分別是getSourceWidth() 、getSourceHeight() 、getDisplayWidth() 、getDisplayHeight() 、getDisplayX() 、getDisplayY()。
到目前位置,我們所做的工作僅僅是如何控制一個攝像頭來取景,而最後一個關鍵步驟則是獲取一張靜態圖片。方法getSnapshot(String imageType)可以按照指定文件格式返回圖片的數據,然後可以利用返回的數據創建一個圖片。其中ImageType是圖片格式,傳進null則是默認的png圖片。
byte[] data;
Image img=null;
data = vc.getSnapshot(null);
img = Image.createImage(data, 0, data.length);
如果想保存圖片,可以存進RMS,或者發送至服務器上,那已超出本文的范圍。
這樣,我們就可以利用攝像頭的功能來豐富游戲的功能。據筆者所知,目前結合攝像頭的游戲還不多,西門子SX1上有一款游戲,內容是打蚊子,游戲的背景就是攝像頭實時拍攝到的畫面,更重要的是,隨著玩家移動或者搖晃手機,游戲能夠計算出手機的移動方向,並改變游戲中蚊子的位置及瞄准器的位置,不能不讓人擊節叫好。