🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

Q&A

解決済

1回答

14418閲覧

「'toDataURL'の実行に失敗した。canvasesは汚染されている。」と出ます。どうすればいいのでしょう・・・

hiryu-

総合スコア8

canvas

HTML5の<canvas>要素用のタグです。CanvasはHTML5から導入された、二次元の図形描写が可能な要素です。

JavaScript

JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

0グッド

2クリップ

投稿2018/08/18 04:52

編集2018/08/18 05:54

前提・実現したいこと

htmlでJavaScriptとCSSを使って、SNSのアイコン等に使えるアバター着せ替えゲームを制作しています

基礎的な着せ替え部分は完成したのですが、肝心の衣装パーツを重ね合わせた状態のpng画像を全て統合した状態でJpg出力するプログラムができていません。

https://www.petitmonte.com/javascript/png_jpeg_gif_convert.html
のサイトを参考にコードを描いてみましたが「Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported.」とのエラーが・・・

「キャンバスが汚染されていて移動できない」とあるので改善策を自分でも探しているのですが、プログラム初心者なのであまりに難易度の高いことを言われても何から学べばいいのかもわからず・・・コードの具体的な修正部分、または参考にできそうなサイト等ありましたらご指南宜しくお願いします。

発生している問題・エラーメッセージ

index.html:41 Uncaught DOMException: Failed to execute 'toDataURL' on 'HTMLCanvasElement': Tainted canvases may not be exported. at onClick (file:///C:/Users/hirose/Desktop/crista/xxxz/%E6%96%B0%E3%81%97%E3%81%84%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC/%E3%83%A9%E3%83%B3%E7%9D%80%E3%81%9B%E6%9B%BF%E3%81%88%20-%20%E3%82%B3%E3%83%94%E3%83%BC/index.html:41:22) at HTMLButtonElement.onclick (file:///C:/Users/hirose/Desktop/crista/xxxz/%E6%96%B0%E3%81%97%E3%81%84%E3%83%95%E3%82%A9%E3%83%AB%E3%83%80%E3%83%BC/%E3%83%A9%E3%83%B3%E7%9D%80%E3%81%9B%E6%9B%BF%E3%81%88%20-%20%E3%82%B3%E3%83%94%E3%83%BC/index.html:145:33)

ソースコード

<!DOCTYPE HTML> <html> <head> <meta charset="UTF-8"> <link rel="stylesheet" href="base.css"> <title>着せ替え</title> <script> function AsciiToUint8Array (S) { var len = S.length; var P = new Uint8Array(len); for (var i = 0; i < len; i++) { P[i] = S[i].charCodeAt(0); } return P; } function SaveToFile(Stream,FileName) { // IE/Edge if (window.navigator.msSaveBlob) { window.navigator.msSaveBlob(new Blob([Stream]), FileName); // それ以外 } else { var a = document.createElement("a"); a.href = URL.createObjectURL(new Blob([Stream])); //a.target = '_blank'; a.download = FileName; document.body.appendChild(a) // FF specification a.click(); document.body.removeChild(a) // FF specification } } function onClick(option){ // JEPGファイルの作成 if (option == 2){ var png = canvas.toDataURL("image/jpeg").replace("data:image/jpeg;base64,",""); // ←エラーが出るのはこの行です png = window.atob(png); var Stream = AsciiToUint8Array(png); SaveToFile(Stream,'dest.jpg'); } } </script> </head> <body> <h1>着せ替えゲーム</h1> <style type="text/css"> #chara { position:relative; height: 800px; width: 566px; } #chara img { position:absolute; left:0; top:0; } </style> <table> <tr> <td> <div id="chara"> <img id="img_jpg" src="images/chara.jpg"> <img id="img_jpg" src="images/kuti1.png" name="kutiLink"> <img id="img_jpg" src="images/mayu1.png" name="mayuLink"> <img id="img_jpg" src="images/me1.png" name="meLink"> <img id="img_jpg" src="images/huku1.png" name="hukuLink"> <br><br> <canvas id="MyCanvas"></canvas> </div> </td> <td> <p> ■口<br> <input type="radio" name="kuti" onClick="kuti1()" value="笑い" checked>笑い <input type="radio" name="kuti" onClick="kuti2()" value="叫び">叫び </p> <p> ■眉<br> <input type="radio" name="mayu" onClick="mayu1()" value="喜び" checked>喜び <input type="radio" name="mayu" onClick="mayu2()" value="困り">困り </p> <p> ■目<br> <input type="radio" name="me" onClick="me1()" value="普通" checked>普通 <input type="radio" name="me" onClick="me2()" value="喜び">喜び </p> <p> ■服<br> <input type="radio" name="huku" onClick="huku1()" value="服1" checked>服1 <input type="radio" name="huku" onClick="huku2()" value="服2">服2 </p> <p> <button onclick="onClick(2);">JPEGファイルの作成</button> </p> </td> </tr> </table> <SCRIPT type="text/javascript"> <!-- //kuti function kuti1(){ document.kutiLink.src = "images/kuti1.png"; } function kuti2(){ document.kutiLink.src = "images/kuti2.png"; } //mayu function mayu1(){ document.mayuLink.src = "images/mayu1.png"; } function mayu2(){ document.mayuLink.src = "images/mayu2.png"; } //me function me1(){ document.meLink.src = "images/me1.png"; } function me2(){ document.meLink.src = "images/me2.png"; } //huku function huku1(){ document.hukuLink.src = "images/huku1.png"; } function huku2(){ document.hukuLink.src = "images/huku2.png"; } // キャンバスの取得 var canvas = document.getElementById("MyCanvas"); canvas.width = 566; canvas.height = 800; // コンテキストの取得 var ctx = canvas.getContext("2d"); var max_height = 0; var imglist = new Array(); imglist[2] = document.getElementById("img_jpg"); // キャンバスに画像を描画 imglist[2].onload = function() { ctx.drawImage(imglist[2],0,max_height); max_height += imglist[2].height+30; }; </SCRIPT> </body> </html>

試したこと

1、imgElement.crossOrigin = 'anonymous';を入れる。

入れる場所が悪いのか入れ方が悪いのか・・・「 imgElement is not defined」とエラーが出る

2、ローカルファイルをhttpサーバ経由でアクセス

「file://...」のローカルファイルはそのままではhttpで開けずブロックされてしまう、という話を聞いたのでhttpで開く方法を探しているのですが・・・

①chromeのショートカットに--allow-file-access-from-filesを追加する方法は無効だと表示され(そもそも普通に起動してjpg保存できるようにしたいのでこの方法は使いたくない)

②scriptをどう弄ればhttpで開けるのか分からない・・・参考サイトも見つからない

といった次第で手詰まり状態なので質問させていただきました。どうぞよろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

m.ts10806

2018/08/18 04:56

エラーもコードと同じようにコードブロックで囲ってください
hiryu-

2018/08/18 06:18

修正しました
guest

回答1

0

ベストアンサー

そもそも普通に起動してjpg保存できるようにしたい

となれば、そして「普通に起動する」が「HTMLファイルをダブルクリックする」という意味であれば、Chromeでなんとかなる方法はありません

<img>crossoriginを足しても、サーバのないfile://環境では、必要なAccess-Control-Allow-Originヘッダが来ないので、汚染フラグを外すことはできません(MDN)。

HTTPで開こうと思えば、適当なサーバを立てる必要がありますが、それにはひと手間必要で、ファイルを開けばそのまま動く、というようにすることはできません。

投稿2018/08/18 05:02

maisumakun

総合スコア145957

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

maisumakun

2018/08/18 05:06

ということで、何かを諦める必要が出てきます。「Webサーバを経由させるために、ファイルから開いて起動するのを諦める」、「Firefoxではfile://のクロスオリジンの定義がゆるいので、そちらで動作すればいいとChromeで動かすのを諦める」など、いくつか選択肢はあります。
hiryu-

2018/08/18 06:17

うーん「hymlファイルをダブルクリックしてchromeですぐに開ける」ことと「ブラウザ上で編集した着せ替え画像をjpgで出力できる」はそれぞれ絶対条件の一つだと考えているので・・・どっちも諦められないですね。 現在私が参考にしてる方のゲームはfile://形式でもちゃんと起動も出力も出来ているので、こうなると根本的な方法の見直しが必要ということになりますかね・・・。まず「表示画像をcanvasに描画して出力」という方法をとったこと自体が間違いだったのかも知れないですね。次は別のやり方でアプローチしてみたいと思います。できればでいいのですが、もしmaisumakun様から「こういう方法はどうか?」といった提案があればお教え頂けると嬉しいです。 ハッキリと解りやすいご回答ありがとうございました。
maisumakun

2018/08/18 06:22

うまくいくかはわからないですが、「元画像をファイルで置いておくのを諦める」という方法はあるかもしれません(HTMLあるいはJavaScriptに`data:`形式で展開して埋め込んでしまう)。
hiryu-

2018/08/19 05:40

わかりました。その方法を調べてみることにします。ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問