CanvasをJpegファイルにして保存したい

2,304 views
Skip to first unread message

teruha najima

unread,
Aug 23, 2013, 3:55:53 AM8/23/13
to html5-dev...@googlegroups.com
PhoneGapの質問になって恐縮なのですが…。

Cameraで撮影した画像を、Canvasに表示し、そしてフレーム画像を重ねてプリクラみたいな事をするアプリケーションを作成しました。
次は、このCanvasの内容を端末側に保存させようとしているのですが、その方法で難儀しております。

まず、真っ先に思いついたのが

var jpegData = myCanvas.toDataURL("image/jpeg");

といった感じに、base64化させて、それをPhoneGapのFile APIを使って保存する方法なのですが、
予想通りというか何と言うか、base64テキストデータが保存されるだけです。

他に何か方法が無いのか模索しているのですが、何か良いアイデアはありませんでしょうか?

Eiji Kitamura

unread,
Aug 23, 2013, 4:18:01 AM8/23/13
to html5-dev...@googlegroups.com
base64化したデータを再度Blobに変換してはいかがでしょう?

var bin = atob(jpegData.split(',')[1]);
var buffer = new Uint8Array(bin.length);
for (var i = 0; i < bin.length; i++) {
  buffer[i] = bin.charCodeAt(i);
}
var blob = new Blob([buffer.buffer], {type: 'image/png'});

※Android BrowserだとBlobの挙動が怪しかったので、try catchでBlobBuilderを使う方法も入れた方が無難かもしれません。

PhoneGapの仕様を知らないので、これをそのまま保存できるか分かりませんが・・・


2013/8/23 teruha najima <fla...@gmail.com>

--
このメールは Google グループのグループ「html5j」の登録者に送られています。
このグループから退会し、メールの受信を停止するには、html5-developer...@googlegroups.com にメールを送信します。
このグループに投稿するには、html5-dev...@googlegroups.com にメールを送信してください。
http://groups.google.com/group/html5-developers-jp からこのグループにアクセスしてください。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。



--
Eiji Kitamura | Developer Advocate | google.com/+agektmr | +81-80-1150-6480

Toshiya TSURU

unread,
Aug 23, 2013, 4:22:25 AM8/23/13
to html5-dev...@googlegroups.com
こんにちは!

PhoneGap (Cordova) だとのことで、
こういうプラグインもあります ^ ^

* Canvas2ImagePlugin
https://github.com/devgeeks/Canvas2ImagePlugin

自力系だと toBlob() でしょうか

http://www.w3.org/TR/2011/WD-html5-20110525/the-canvas-element.html#dom-canvas-toblob


2013/8/23 teruha najima <fla...@gmail.com>:
> --
> このメールは Google グループのグループ「html5j」の登録者に送られています。
> このグループから退会し、メールの受信を停止するには、html5-developer...@googlegroups.com
> にメールを送信します。
> このグループに投稿するには、html5-dev...@googlegroups.com にメールを送信してください。
> http://groups.google.com/group/html5-developers-jp からこのグループにアクセスしてください。
> その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。



--
++++++++++++++++++++++++++++++++++◆◇◆
株式会社 サンビジネス / Sunbusiness, Inc.
システム開発部 / Software Development Division
津留 敏哉 / Toshiya TSURU <t_t...@sunbi.co.jp>

TEL 03-3455-5294(代) / +81+3-3455-5294
FAX 03-3455-8909 / +81+3-3455-8909
〒105-0014
東京都港区芝1-10-11 コスモ金杉橋ビル / Shiba 1-10-11, Minato, Tokyo, Japan
http://www.sunbi.co.jp/
+++++++++++++++++++++++++++++++++++++++

teruha najima

unread,
Aug 25, 2013, 10:08:00 PM8/25/13
to html5-dev...@googlegroups.com
Eiji Kitamuraさん、Toshiya TSURUさん、アドバイスありがとうございます。

Blobメソッドの存在は初めて知りました。
古いOS(Android 2.3とか、iPhone4とか)でも使えるメソッドか心配ですが、ちょっと試してみます。

一番良いのは、素直にPlugIn利用なのかな…?

teruha najima

unread,
Aug 25, 2013, 11:32:31 PM8/25/13
to html5-dev...@googlegroups.com
関数を作って動作を試してみました。
結論から言えば、iOS側はエラーも出ませんが保存もされず、android側はエラーで動作せず、です。

 Uncaught ReferenceError: BlobBuilder is not defined at file:///android_asset/www/...

PlugInしか無いのかなあ。:-(

---------------------------------------------------------------------------------

function imgSave3(){

                    var base64 = myCanvas.toDataURL("image/jpeg");

                    var blob = base64toBlob(base64);

                    saveBlob(blob);

                }

                

                function saveBlob(_blob)

                {

                    var url = (window.URL || window.webkitURL);

                    var jpegData = url.createObjectURL(_blob);

                    window.requestFileSystem(LocalFileSystem.PERSISTENT, 0, gotFS, saveFail);                    

                    function gotFS(fileSystem) {

                        fileSystem.root.getFile("test.jpg", {create: true}, gotFileEntry, saveFail);

                    }

                    function gotFileEntry(fileEntry) {

                        fileEntry.createWriter(gotFileWriter, saveFail);

                    }

                    function gotFileWriter(writer) {

                    writer.onwrite = function(evt) {

                            alert("write success");

                    };

                    writer.write(jpegData);

}

function saveFail(m){

                    alert("saveFail()"+m);

                    }

                }

                

                

                function base64toBlob(_base64)

                {

                    var i;

                    var tmp = _base64.split(',');

                    var data = atob(tmp[1]);

                    var mime = tmp[0].split(':')[1].split(';')[0];

                    var buff = new ArrayBuffer(data.length);

                    var arr = new Uint8Array(buff);

                    for (i = 0; i < data.length; i++) {arr[i] = data.charCodeAt(i);}

                    

                    var blob;

                    try{

                    blob = new Blob([arr], { type: mime });

                    }catch(ex){

                    var bb = BlobBuilder();

bb.append(arr);

blob = bb.getBlob();

                    }

                    return blob;

                }

---------------------------------------------------------------------------------


tzik

unread,
Aug 26, 2013, 2:12:41 AM8/26/13
to html5-dev...@googlegroups.com
BlobBuilderをWebKitBlobBuilderにしてもだめでしょうか?
BlobBuilderは最近の仕様/実装からは除かれていますが、WebKitから除かれる前にはprefix付きでした。

2013/8/26 teruha najima <fla...@gmail.com>

--
このメールは Google グループのグループ「html5j」の登録者に送られています。
このグループから退会し、メールの受信を停止するには、html5-developer...@googlegroups.com にメールを送信します。
このグループに投稿するには、html5-dev...@googlegroups.com にメールを送信してください。
http://groups.google.com/group/html5-developers-jp からこのグループにアクセスしてください。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。



--
立木 泰樹 (TSUIKI Taiju, tzik)
mail: ma...@tzik.jp

teruha najima

unread,
Aug 26, 2013, 4:32:20 AM8/26/13
to html5-dev...@googlegroups.com, ma...@tzik.jp
立木 泰樹さん

アドバイスありがとうございます。
WebKitBlobBuilderに書き換えて試してみましたが、状況は変わりませんでした。

特にiOSですと


 try{
blob = new Blob([arr], { type: mime });

部分で例外が発生せず、何がいけないのかすら謎です。

 alert("write success");

が実行されているあたり、そこまでは問題が無さそうなんですけれど… :-(

時間がもったいないので、津留 敏哉さんが教えてくれたCanvas2ImagePluginを利用する事にします。
(Canvas2ImagePluginを入れたら「Classes/CDVInAppBrowser.h:59:1: No 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed」が出て、頭を抱えている所です)

ありがとうございました。


2013年8月26日月曜日 15時12分41秒 UTC+9 tzik:
BlobBuilderをWebKitBlobBuilderにしてもだめでしょうか?
BlobBuilderは最近の仕様/実装からは除かれていますが、WebKitから除かれる前にはprefix付きでした。

2013/8/26 teruha najima <fla...@gmail.com>
このグループから退会し、メールの受信を停止するには、html5-developers-jp+unsubscribe@googlegroups.com にメールを送信します。
このグループに投稿するには、html5-develo...@googlegroups.com にメールを送信してください。

http://groups.google.com/group/html5-developers-jp からこのグループにアクセスしてください。
その他のオプションについては、https://groups.google.com/groups/opt_out にアクセスしてください。

teruha najima

unread,
Aug 26, 2013, 6:12:20 AM8/26/13
to html5-dev...@googlegroups.com
PhoneGapプラグインを使う事で解決しました。
html5jとは関係ない解決方法になってしまって申し訳ないです。

【iOS側】
Canvas2Image使用
https://github.com/devgeeks/Canvas2ImagePlugin

・現在も解決されない問題
01. pngで保存される。jpegで保存したかったんですが仕方が無いのかな…。
02. 無関係なはずの「CDVInAppBrowser.h」に「No 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed」警告がでている。(なんで?)
アドバイスありがとうございました。

2013年8月23日金曜日 16時55分53秒 UTC+9 teruha najima:
Reply all
Reply to author
Forward
0 new messages