JavaScriptでcanvasに描画した画像を保存・読み込みする方法

このQ&Aのポイント
  • JavaScriptのcanvasで描いた画像を保存して、読み込む方法について教えてください。
  • canvas.toDataURL()で画像データを取得し、LocalStorageに保存することはできていますが、その後Canvasに描画できない問題が発生しています。
  • どのようにすれば保存した画像を読み込んでCanvasに描画できるのでしょうか?
回答を見る
  • ベストアンサー

javascriptで困っています。教えてください

html5でcanvasに描いた画像をsave_buttonを押してlocalStorageで保存して、それをload_buttonをおして読み込もうとしているのですが、うまくいきません。 canvas.toDataURL();でデータを6bit毎に分割できています。 それを保存して、 var base64 = window.localStorage.getItem("saveKey");で読み込むこともできています。 その後canvasに描画できません。 よろしくお願いします。 var canvas = document.getElementById("myCanvas"); $("#save_button").click(function () {    // Canvasからbase64エンコーディングされた画像データを取得する var canvas = document.getElementById("myCanvas"); var base64 = canvas.toDataURL(); // LocalStorageに保存する window.localStorage.setItem("saveKey", base64); }); $("#load_button").click(function () { // LocalStroageからデータを取得する var base64 = window.localStorage.getItem("saveKey"); // Imageオブジェクトを作成し、src属性にデータを設定する var image = new Image(); image.src = base64; image.onload = function(){ // 画像の読み込みが終わったら、Canvasに画像を反映する。 canvas.drawImage(image, 0, 0); } });

  • dkong
  • お礼率86% (170/197)

質問者が選んだベストアンサー

  • ベストアンサー
  • fujillin
  • ベストアンサー率61% (1594/2576)
回答No.2

dataStorageって使ったことがないので、わからないのですが… これでもだめでしょうか? (全角空白は半角にしてください) Fxで動作確認 $("#load_button").click(function () {  var base64 = window.localStorage.getItem("saveKey");  var image = new Image();  image.onload = function(){  //念のため順序を入替え // canvas.drawImage(image, 0, 0);  //以下に変更   canvas.getContext('2d').drawImage(image, 0, 0); //←変更  }  image.src = base64; }); [ 参考 ] http://www.html5.jp/canvas/ref.html

dkong
質問者

お礼

ありがとうございます。コンテキストの取得で間違いがありました。参考になりました。

その他の回答 (1)

回答No.1

Safariにて、localStorageに保存した画像データをImage()で表示できなくなるという現象を確認しています。 私のケースではFirefox24では期待通り表示されますが、 他のブラウザではどうでしょうか。 なお、localStorageに保存せずに、canvasからImage()に、そのImage()をあらためてcanvasに描画すると、期待通り動作する事は確認しています。 ブラウザのバグなら何か別のフォーマット(独自フォーマット)にエンコードしてlocalStorageに保存、表示時はbase64にデコードして使用とすればいけるかもしれませんが、その方法は試していません。 ご参考まで。

dkong
質問者

お礼

情報ありがとうございます。参考にさせていただきます。

関連するQ&A

  • javascriptのcanvasについて

    先日こちらで質問させて頂き、頂いた回答をもとに javascriptのcanvasについて勉強を続けていて、 canvasを2つ重ねたカラーシミュレーションのようなものを作りたいと考えています。 先日教えて頂いた内容をもとに 下記のような記述で2枚目のcanvasの画像を入れ替えることや、 色を変更することは出来ました。 ただ、「進む」ボタンや「戻る」ボタンを押したときに 色がもとの色に戻ってしまうので、色は固定されたまま(この記述でいうと茶色や赤)で 画像を入れ替える方法がわからずにいます。 なにか良い方法はないでしょうか。 <style type="text/css"> .canvas001 { position: absolute; top:100px; left:0px; } .canvas002{ position: absolute; top:100px; left:0px; } </style> <script> onload = function() { image1(); image2(); image3();}; function image1() { var cnvs = document.getElementById('canvas1'); var ctx = cnvs.getContext('2d'); var img = new Image(); img.onload = function() { ctx.drawImage(img, 0, 0); }; img.src = "face.png"; }; function image2() { var cnvs = document.getElementById('canvas2'); var ctx = cnvs.getContext('2d'); var img = new Image(); img.onload = function() { ctx.drawImage(img, 0, 0); }; img.src = "hair1.png"; }; var src = [  'hair1.png',  'hair2.png',  'hair3.png' ]; var currentIndex = 0; var currentImage; function hair(){ var img = currentImage = new Image(); img.onload = function() { if(currentImage === img){ var cnvs = document.getElementById('canvas2'); var ctx = cnvs.getContext('2d'); ctx.clearRect(0, 0, cnvs.offsetWidth, cnvs.offsetHeight); ctx.drawImage(img, 0, 0); } }; img.src = src[currentIndex]; } window.back = function(){ currentIndex = (currentIndex - 1 + src.length) % src.length; hair(); } window.foward = function(){ currentIndex = (currentIndex + 1) % src.length; hair(); } function black(){ var ctx = document.getElementById("canvas2").getContext("2d"); var imagedata = ctx.getImageData(0,0,300,300); var idata = imagedata.data; var num = idata.length; var pix = num / 4; for ( var i = 0 ; i < pix ; i++ ){ var r = idata[ i*4 ]; var g = idata[ i*4 + 1 ]; var b = idata[ i*4 + 2 ]; idata[ i*4 ] = 35; idata[ i*4 + 1 ] = 24; idata[ i*4 + 2 ] = 21; } ctx.putImageData(imagedata,0,0); } function brown(){ var ctx = document.getElementById("canvas2").getContext("2d"); var imagedata = ctx.getImageData(0,0,300,300); var idata = imagedata.data; var num = idata.length; var pix = num / 4; for ( var i = 0 ; i < pix ; i++ ){ var r = idata[ i*4 ]; var g = idata[ i*4 + 1 ]; var b = idata[ i*4 + 2 ]; idata[ i*4 ] = 140; idata[ i*4 + 1 ] = 96; idata[ i*4 + 2 ] = 37; } ctx.putImageData(imagedata,0,0); } function red(){ var ctx = document.getElementById("canvas2").getContext("2d"); var imagedata = ctx.getImageData(0,0,300,300); var idata = imagedata.data; var num = idata.length; var pix = num / 4; for ( var i = 0 ; i < pix ; i++ ){ var r = idata[ i*4 ]; var g = idata[ i*4 + 1 ]; var b = idata[ i*4 + 2 ]; idata[ i*4 ] = 182 ; idata[ i*4 + 1 ] = 0; idata[ i*4 + 2 ] = 5; } ctx.putImageData(imagedata,0,0); } </script> <body> <div> <div class="canvas001"><canvas id="canvas1" height="300"></canvas></div> <div class="canvas002"><canvas id="canvas2" height="300"></canvas></div> </div> <div> <form><div> <INPUT TYPE=button NAME="submit" VALUE="戻る" onClick="back()"> <INPUT TYPE=button NAME="submit" VALUE="進む" onClick="foward()"> </div></form> </div> <img src="btn_black.png" onclick="black()" > <img src="btn_brown.png" onclick="brown()" > <img src="btn_red.png" onclick="red()" > </body>

  • javascriptのcanvasについて

    HTML5のcanvasを勉強しています。 canvas内にローカル画像を表示させ(サーバにアップロードはしないで)、 その画像の拡大や縮小、上下左右の移動などの操作が出来るようなものにしたいと考えているのですが、なかなかうまく出来ません。 先日もjavascriptでの画像の拡大縮小などについて質問させて頂いたのですが どうしてもうまく出来ずにいます。 サンプルや見本を探しながら下記のような記述になったのですが、 希望としているローカル画像を表示し拡大縮小することや、 左右上下に動かすことの記述がわからずにいます。 解決方法など教えて頂けましたら幸いです。 <!DOCTYPE html> <html> <head> <meta charset="UTF-8" /> <title>test</title> <meta name="Description" content="" /> <meta name="Keywords" content="" /> <script src="http://ajax.googleapis.com/ajax/libs/jquery/2.0.3/jquery.min.js"></script> <script> var rectWidth = 100; var rectHeight = 500; var theta = 10; var MyCanvas; var ConMode; var RotateState = 0; var Img = document.createElement('img'); Img.src = "http://sites.google.com/site/westinthefareast/home/datafiles/Desert.jpg"; var ImgWidth = 204.8; var ImgHeight = 153.6; //キャンバスがロードされてから初期処理を行う onload = function() { //キャンバスオブジェクトへの参照をセット MyCanvas = document.getElementById("DrawField"); //キャンバスの大きさを400px×400pxにする MyCanvas.setAttribute('width', '400'); MyCanvas.setAttribute('height', '400'); //2次元描画用コンテキストを設定 ConMode = MyCanvas.getContext('2d'); //キャンバスの座標系を0,0(左上)からキャンバスの中心に移動する ConMode.translate(MyCanvas.width/2,MyCanvas.height/2); //読み込んだ画像イメージを指定のサイズでキャンバスの中心に表示する ConMode.drawImage(Img,-ImgWidth/2,-ImgHeight/2,ImgWidth,ImgHeight); }; //画像を縮小表示する処理 function ShrinkView(){ //表示された画像を消す ConMode.clearRect(-ImgWidth/2-10,-ImgHeight/2-10,ImgWidth+20,ImgHeight+20); //画像の大きさを0.833倍にする ImgWidth = ImgWidth/1.2; ImgHeight = ImgHeight/1.2; //画像の重心がキャンバス座標の中心点にくるように画像を表示する ConMode.drawImage(Img,-ImgWidth/2,-ImgHeight/2,ImgWidth,ImgHeight); } //画像を拡大表示する処理 function ExpandView(){ //表示された画像を消す ConMode.clearRect(-ImgWidth/2-10,-ImgHeight/2-10,ImgWidth+20,ImgHeight+20); //画像の大きさを1.2倍にする ImgWidth = ImgWidth*1.2; ImgHeight = ImgHeight*1.2; ConMode.drawImage(Img,-ImgWidth/2,-ImgHeight/2,ImgWidth,ImgHeight); } </script> </head> <body> <input type="file" id="selfile"><br><br> <form> <canvas id="DrawField" style="border:solid"></canvas> <input id= "Shrink" type=button value="縮小" onClick="ShrinkView()"> <input id= "Expand" type=button value="拡大" onClick="ExpandView()"> <input id= "Right" type=button value="右" onClick="right()"> <input id= "Left" type=button value="左" onClick="right()"> <input id= "Up" type=button value="上" onClick="up()"> <input id= "Down" type=button value="下" onClick="down()"> </form> </body> </html>

  • chart.jsの複数グラフの画像化の方法

    いつもお世話になっております。前々回 https://okwave.jp/qa/q9834370.htmlでグラフを複数個表示する方法 を教えてもらいましたが、今回は、表示された複数個のグラフを同時に.toBase64Image()関数か.toDataURL()メソッドで画像化することが出来ないかと思い投稿いたしました。グラフが1個の場合は私にも var canvas = document.getElementById('myPieChart'); var image = canvas.toDataURL(); とか var image = myBarChart.toBase64Image(); とかで出来るのですが、base64エンコード文字列として複数個の場合1度別のcanvas要素に纏めてから読み込むのかあるいは個々に読み込み再配置するのかこのまま読み込めるかもさっぱり見当がつかない状態です。ご教授のほど宜しくお願いいたします。

  • localStorage

    今までCookieを使っていたのですが、最近localStorageの存在を知り使ってみました。 質問ですが、サンプルを参考に下記のフォームを作りました。 無事に値を取り出せ、document.writeで文字の方は表示できるのですが、 img srcの画像の表示方法がわかりません。 document.write("<img src='localStorage.uUrl'>");←これが間違っているのはわかるのですが、 1.htmlのURLフォーム欄に、http://cmm001.goo.ne.jp/img/logo/goo.gif を書いて、2.htmlで表示する方法を教えて下さい。 ----1.html---- <script> (function(){ // 最初にローカルストレージが使えるか調べる。使えない場合は何もしない if (!window.localStorage) return; // ローカルストレージからフォームにデータを戻す document.getElementById("uName").value = window.localStorage.getItem("uName") || ""; document.getElementById("uUrl").value = window.localStorage.getItem("uUrl") || ""; // データ送信時にローカルストレージにフォーム内容を保存する document.getElementById("dataForm").addEventListener("submit", function(){ window.localStorage.setItem("uName", document.getElementById("uName").value); window.localStorage.setItem("uUrl", document.getElementById("uUrl").value); alert("データを保存しました"); }, true); })(); </script> <h1>ローカルストレージを利用したフォーム</h1> <form id="dataForm" method="post" action="" onsubmit="return false"> 名前:<input type="text" name="uName" id="uName"><br> URL:<input type="text" name="uUrl" id="uUrl"><br> <input type="submit" value="送信"> </form> ----2.html---- <script> (function(){ // ローカルストレージからフォームにデータを戻す document.getElementById("uName").value = window.localStorage.getItem("uName") || ""; document.getElementById("uUrl").value = window.localStorage.getItem("uUrl") || ""; document.write(localStorage.uUrl); document.write("<img src='localStorage.uUrl'>"); })(); </script>

  • javascriptで困ってます

    下記のスクリプトでcanvas上で四角を動かすアニメーションをさせたのですが、andoroidに標準のブラウザで見ると、最初の位置に四角が残ってしまいます。この残ってしまう四角を消したたいのですが、どのようにしたらよいのでしょうか、教えてください。よろしくお願いします。 <!doctype html> <html> <head> <meta charset="UTF-8"> <title>canvasアニメーション</title> <script type="text/javascript"> // <![CDATA[ window.onload = function(){ var canvas = document.getElementById("canvas"); var ctx = canvas.getContext("2d"); ctx.fillStyle = "#ffffff"; var point = {x:0,y:0}; var par = {x:3,y:3}; var timer; var delay = 100; function draw(x,y){ ctx.clearRect(0,0,600,600); ctx.fillRect(x,y,50,50); } var loop = function(){ point.x = point.x + par.x; point.y = point.y + par.y; draw(point.x,point.y); clearTimeout(timer); timer = setTimeout(loop,delay); } loop(); } // ]]> </script> <style type="text/css" media="screen"> /* <![CDATA[ */ body{ background-color:#000000; } /* ]]> */ </style> </head> <body> <canvas id="canvas" width="600" height="600"></canvas> </body> </html>

  • JSの保存ダイアログについて

    以下のコードは簡易メモ的なものです そこに書き込まれた内容を保存できるようにしたいのですがfunction dl()には何を書けばいいのでしょうか? 調べてみて function dl(C:\){ var a = document.createElement('a'); a.href = C:\; a.setAttribute('dl', name || 'noname'); a.dispatchEvent(new CustomEvent('click')); } としてみたのですがこれを書き込むと保存ダイアログはおろかtextの保存もできなくなってしまいます <input type="text" id="title"><br><br> <textarea id="memo" rows="8" cols="50"></textarea><br><br> <input type = "button" value="SAVE" onclick="dl();"> <script> var title = document.getElementById("title"); var memo = document.getElementById("memo"); window.onload = function() { var body_title = localStorage.getItem("title"); if (body_title != null) title.value = body_title; var body_memo = localStorage.getItem("memo"); if (body_memo != null) memo.value = body_memo; } title.onchange = function() { localStorage.setItem("title",title.value); } memo.onchange = function() { localStorage.setItem("memo",memo.value); } function dl(){ } </script>

  • javascriptで困っています。教えてください

    canvasタグの画像の描画で困っています。 Imageオブジェクトを生成して、画像ファイルを先読みしておいて var aaa = new Image(); aaa.src = "img/item00.png"; var bbb = new Image(); bbb.src = "img/item01.png"; 配列に入れる var i = [aaa,bbb] 描画コンテキストの取得s取得して、画像を表示させる var canvas = document.getElementById('sample'); if (canvas.getContext) { var context = canvas.getContext('2d'); 座標(10, 10)(50, 50)の位置にイメージを表示 context.drawImage(aaa, 10, 10); context.drawImage(bbb, 50, 50); } としています。このあとクリックなどのきっかけで、画像の絵を入れ替えたいと思い、 var cha1 = i[0].src; var cha2 = i[1].src; i[0].src = cha2; i[1].src = cha1; もう一度描画させているのですが、うまくいきません。 cha1,cha2が取得できているかチェックすると、undifineとでます。 これでは、入れ替えることがでないのでしょうか? 入れ替えるとしたらどのような方法があるのでしょうか。 よろしくお願いします。

  • javascriptでのパス指定について

    現在、SpringMVCのビュー部分で、JSPからjavascriptを使用するようにして開発を行っています(初心者です)。html5のcanvasを使用してcanvas内に画像を表示したいのですが、画像表示時のパスの指定が悪いせいか表示されません。そこで、javascriptからのパスの指定方法をご教授頂けないでしょうか? プロジェクト階層とビュー部分のjsp(input.jsp)コード(一部抜粋)は以下になります。 【階層(一部抜粋)】 test <- プロジェクト  |--- WebContent       |----WEB-INF            |----jsp            |    |---input.jsp            |----sample                |---abc.png 【input.jsp】 <body> <canvas id="myCanvas" width="400"; height="400" ;> HTML5 Canvasに対応したブラウザーを使用してください。 </canvas> <script type="text/javascript"> var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext('2d'); ctx.beginPath(); ctx.strokeRect(300, 10, 200, 200); var img = new Image(); img.src = "../sample/abc.png"; //ここでパスを指定。 /* 画像を描画 */   ctx.drawImage(img, 0, 0); </script> <form:form commandName="example"> <form:input path="message"/> <input type="submit" /> </form:form> </body> </html> 【やりたいこと】 WEBブラウザ上に任意の画像を表示して、ユーザーがその画像をマウスで拡縮を行うようなサービスの作成を検討しており、現在、その実装(技術検討)中です。

  • HTML5のcanvasで描画がされない

    HTML5のcanvas要素を使って描画をしようとしたのですが、図形が表示されません。 コードは以下の通りです。 ・index.html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>canvasで図形を描く</title> <script type="text/javascript" src="paint.js"></script> </head> <body onLoad="draw()"> <canvas id="mycanvas"width="800" height"800"> </canvas> </body> </html> ・paint.js function draw() { //描画コンテキストの取得 var canvas = document.getElementById('mycanvas'); if (canvas.getContext) { var ctx = canvas.getContext('2d'); ctx.arc(180,150,20,Math.PI*1,Math.PI*2,true); } } このコードでは(180,150)の位置に半径20の円が描画されるはずなのですが、何も表示されませんでした。 どこかコードに誤りがあるのでしょうか? よろしくお願いします。

  • 複数選択した画像のキャンバスへの描画につい

    HTML5のタグを <input type="file" id="fileInput" multiple /> として、 ファイル選択のonchageイベントで、 選択した画像をキャンバスに50pxずつずらして描画しようとしたところ、 選択ファイルが2つまでなら、うまく描画されますが、4つになると、何故か最後の 画像ファイルしか描画されません(1~3番目に選択した画像ファイルは描画されない)。 選択した画像ファイルをすべて表示するにはどうしたらいいのか教えてください。 宜しくお願いします。 コードは次のとおりです。 document.getElementById('fileInput').onchange = function() { var canvas = document.getElementById('myCanvas'); var ctx = canvas.getContext("2d"); var drwX = 0, drwY = 0;//描画初期位置 var files = this.files; // 選択されたファイルを取得 for (var i = 0; i < files.length; ++i) { var file = this.files[i]; // 画像ファイル以外は処理中止 if (!file.type.match(/^image\/(png|jpeg|gif)$/)) continue; var image = new Image(); var reader = new FileReader(); reader.onload = function(evt) { image.onload = function() { ctx.drawImage(image, drwX, drwY, 50, 50); }; drwX += 50;//次の画像の描画位置を右へ50px drwY += 50;//              下へ50px // 画像のソースに、ファイルのURLを設定 image.src = evt.target.result; } // 読み込んだデータをBase64でエンコードしURLへ reader.readAsDataURL(file); } }