2012年5月9日 星期三

使用HTML5/Javascript做一個像Instagram的相機 (Only works on Opera mini)

Instagram是一個我一直蠻喜歡的service, 主要是簡單, 加上有一些濾鏡可以豐富我隨手拍的照片, 當然, 重要的是, 高價賣給了Facebook而一炮而紅

上星期, 參加了AT&T Palo Alto Hackthon, 拿到大獎的團隊用了一個lib叫 caman.js 的, 這東西讓我有點小小驚艷, 它光用javascript (其實是Coffee script)就實作出了許多影像處理的功能, 這讓我興起想用這個來試著做出類似Instagram的東西, 當然是純用HTML+Javascript

首先面臨的一個問題是, 實作Camera的部份, HTML5支援media capture的方式有三種(請參考Reference 3) : Input tag, device tag, WebRTC (getUserMedia)

但很不幸, 除了Input tag以外, 大部分手機上的browser,如Android browser, Firefox, Chrome, 可以說幾乎全部都不支援, 這可真是有點令人傷心的消息, 因為用Input tag, 會離開browser跳到另一個程式, 這樣就無法結合自己的UI了

不過, 其實也沒那麼絕望, Android上的Opera Mini, 就支援getUserMedia (參考Reference 1)

因此就可以實作出像這樣的東西:

Device-2012-05-10-021018

WebRTC(getUserMedia)的原理是把media stream導到video tag去播放(理應就這樣做), 但這樣出來的比例是camera的比例, Instagram的照片都是方形的, 要實現這點, 其實也不難, 就另外把內容畫到另一個方形canvas, 在video play的時候開始每隔40ms畫一次, 把video畫到canvas的方式也不難, 就把他當image看待就行了

不過當第一次使用時, 瀏覽器會跳出詢問是否允許使用相機的對話窗:

Device-2012-05-10-021029

因為偷懶, 拍照的部份沒沿用原本的canvas, 另起一個Canvas, 並把可用的濾鏡放在下面:

Device-2012-05-10-021056

接下來就是神奇的CamanJS的工作了, CamanJS是一個以CoffeeScript實作出來的影像處理的lib, 還真的蠻厲害的, 害我都有點想研究一下CoffeeScript了

使用方式非常的簡單, 像以下面的程式:

Caman("path/to/image.jpg", "#canvas-id", function () {

    // manipulate image here

    this.brightness(5).render();

});

就可以提高影像的亮度了,

此外還有許多預設的濾鏡, 我也偷懶直接採用, 這就是做出來的效果:

Device-2012-05-10-021122
Device-2012-05-10-020928

Source codes分享於此: https://github.com/julianshen/instagramlikecam

References: 

  1. http://dev.opera.com/articles/view/playing-with-html5-video-and-getusermedia-support/
  2. http://people.opera.com/danield/webapps/instant-camera/
  3. http://www.html5rocks.com/en/tutorials/getusermedia/intro/
  4. http://camanjs.com/

2012年5月7日 星期一

[筆記] Self published B2G app

B2G並未一定要開發者把應用程式發表到一個特別的app store, 網站也可以自行加一個install按鍵, 讓使用者把你的網站當應用程式裝到手機內

首先, 你必須要先有個manifest, 目前manifest並沒強制的檔名, 但文件裡建議叫 xxxx.webapp, 以下是範例內容:

 

{ "name": "MyTestApp", "description": "test app", "launch_path": "/", "icons": { "128": "/img/icon.png" }, "developer": { "name": "Julian Shen" } }

 

然後在網頁內加上檢查是否安裝, 以及安裝的程式碼, 範例如下:

var manifestUrl = 'http://localhost:3000/manifest.webapp'; var app = navigator.mozApps;  function checkInstalled() { var request = app.getSelf(); request.onsuccess = function() { if(request.result) { //installed console.log('installed'); document.getElementById('installmsg').style.display='none'; } else { //not installed console.log('not installed'); } }; }  function install(cb) { var request = app.install(manifestUrl); request.onsuccess = function() { alert('installed'); };  request. function() { alert('Not installed'); } }
這邊要注意的是manifestUrl必須是full path而不是只有相對位置, 寫相對位置, 它還是讀的到, 但會出parse error, 之前害我搞半天一直以為是格式問題, trace了一下Webapps.js, 發現可能是判斷install origin有問題
目前安裝介面很醜:
_2012-05-08_2
安裝完就可以在Home screen看到它的存在了:
_2012-05-08_2