Canvasから画像書き出ししてTitaniumに渡す
2011 年 4月 21 日 木曜日 kosuketitaniumのWebViewに配置したcanvasに描いたイメージをファイルに保存する方法。
ユーザーにcanvasで何かを描かせたらそのデータをファイルに保存したいことも多いはず。作文メーカーを作った時に調べたところWebViewの中のcanvasとtitaniumでデータを受け渡す方法が2つありました。
1.htmlファイル(canvasタグを書いたhtmlファイル)のJavaScriptでTitanium.App.fireEventでイベントを送信しイベントオブジェクトにcanvasのデータを添付する。
2.titaniumのjsからWebViewのevalJSメソッドを使って、htmlファイルに書いたcanvasのデータをreturnするJavaScriptを実行する。
作文メーカーでは2の方法を使っています。
まず、canvasでイメージデータに変換するにはtoDataURL() メソッドを使います。
以下のページを参考にしました。
toDataURL() メソッド – Canvasリファレンス – HTML5.JP
一つ問題があります。
toDataURL();
の戻り値はbase64でエンコードされた文字列なのですが、その先頭にmimetypeが含まれるようです。
data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAABcIAAAQqCAYAAABk7.... |
titaniumでファイルに保存する場合、このmimetypeが後々問題になりますので、どこかの段階で削除します。今回はtoDataURL()を実行した直後にreplaceで文字列から削除することにしました。最初の,以前を削除して以下のようなデータに整形します。
iVBORw0KGgoAAAANSUhEUgAABcIAAAQqCAYAAABk7.... |
この処理をまとめたのが以下の関数です。
function output(){ var cvs = document.getElementById( "stage" ); var src = cvs.toDataURL("image/png").replace(/^.*,/,''); return src; } |
この関数をtitaniumから実行して戻り値をファイルに変換します。
データをデコードしてファイルに書き込めば完了です。デコードするときにmimeTypeがあるとうまくいかないので削除しておく必要があったという具合でした。
var result = webview.evalJS("output();"); var base64 = Titanium.Utils.base64decode(result); var file = Titanium.Filesystem.getFile( Titanium.Filesystem.tempDirectory, "_TEMP_.png" ); file.write( base64 ); |
Canvasに解像度を設定する
2011 年 4月 20 日 水曜日 kosuke先日リリースしたオリジナルアプリ作文メーカーでは、ユーザー操作で描く文字の描画にCanvasを使っています。
titanium mobileでは描画APIが標準で用意されていない為、WebViewをつかってCanvasで代用した形です。僕はCanvasを使うのはこれが初めてでしたので、実装をCanvasでなく正攻法でいって描画系のモジュールを使うなどでも同じように1からだったのですが、Canvasでもそれなりにパフォーマンスが出るようだし、やはり僕のようなWeb系のデベロッパー/デザイナーにはWebの技術を使ったほうが間違いや不安も少ないと思ったので。今回のは単純な使い方だったしね。
このCanvasを使うにあたって疑問がありました。Ratina Display(640×960)の機種と通常ディスプレイ(320×480)の機種で使いわける必要があるのか?具体的にはキャンバスのサイズはどちらに設定すればいいのか?という点。開発時点ではRatina Displayの確認環境がなかったので、かなり疑問でした。
もう一つ、今回はアプリで使うデータになるので、Canvasで描いたものをtitaniumに渡さなくてはいけない。これできるの?という点。
結果的にどちらも疑問は解消したのですが、初めてってこともあって右往左往と調べたりしたので2回に分けてメモしておきます。参考になる方もいるかもです。
とりあえず今回は前者の疑問、サイズの問題。これをCanvasに解像度を設定すると題して説明します。