質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
canvas

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

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

Q&A

解決済

1回答

2020閲覧

canvasで画像を相対パスで表示させたい

nyakorobin

総合スコア2

canvas

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

Vue.js

Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

JavaScript

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

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

CSS

CSSはXMLやHTMLで表現した色・レイアウト・フォントなどの要素を指示する仕様の1つです。

0グッド

0クリップ

投稿2020/05/02 02:23

編集2020/05/03 06:50

前提・実現したいこと

canvasで相対パスを使って画像を表示させたい

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

srcを相対パスで書くと、画像が表示されなくなります。
エラーメッセージは出ていません。
パスの指定は間違っていません。

該当のソースコード

html

1<div class="container"> 2 <canvas ref="canvas" class="main-img"></canvas> 3</div>

js

1<script> 2export default { 3 name: 'MainCanvas', 4 methods: { 5 draw() { 6 const canvas = this.$refs.canvas 7 canvas.height = canvas.width; 8 const ctx = canvas.getContext('2d'); 9 const src = "../assets/images/hoge.png" // ここが相対パスだとうまくいかない 10 const img = new Image(); 11 img.onload = function() { 12 ctx.beginPath(); 13 ctx.drawImage(this, 0, 0, canvas.width, canvas.height); 14 } 15 img.src = src; 16 } 17 }, 18 mounted() { 19 this.draw(); 20 } 21} 22

試したこと

相対パスではなく、絶対パスで書くと画像が表示されました。

追記

相対パスで表示したかったのはcanvas内の画像の保存がしたかったためです。

js

1canvas.toBlob(function(blob) { 2 var newImg = document.createElement("img"), 3 url = URL.createObjectURL(blob); 4 5 newImg.src = url; 6 document.body.appendChild(newImg); 7});

上記のようにしたところ、試しに書いた図形はimg属性として画面に表示されましたが、画像部分は表示されませんでした。

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

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

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

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

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

AkitoshiManabe

2020/05/02 03:34

なぜ絶対PATHではだめなのでしょうか。
nyakorobin

2020/05/03 00:42

絶対パスだと toDataUrl() で画像URIが取得できないからです。
nyakorobin

2020/05/03 01:41

もう少し詳しく知りたいです、、、
AkitoshiManabe

2020/05/03 02:09 編集

クロスオリジンの ImageをCanvasに描いたとき、直接 DataURLを取得できない。なら、間接的にDataURLの取得を試みます(ドキュメント上の他のオブジェクトを仲介する案です)。 【Ajax経由の方法】は、先程、案内したリンク先の「例」セクションが URL.createObjectURL() を使って image.src に渡しています。 また、CanvasをImage描画用とDataURL取得用とで分けて、描画後に drawImage(canvas, ...args) を使ってコピーする。ImageData (TypedArray:Uint8ClampedArray)をコピーする。といった方法も思いつきます。
nyakorobin

2020/05/03 06:51

> CanvasをImage描画用とDataURL取得用とで分けて、描画後に drawImage(canvas, ...args) を使ってコピーする。ImageData (TypedArray:Uint8ClampedArray)をコピーする。 この方法を試してみましたが、画像部分は表示されませんでした。
AkitoshiManabe

2020/05/03 09:45

回答欄に追記しました。 もし、管理下になく応答ヘッダを変更できない場合は、管理下にあるサーバーを介するしかなさそうです。
guest

回答1

0

ベストアンサー

相対パスで表示させたい

絶対PATHで扱うほうが、デッドリンクを避けやすいと思います。

追記ここから)
Canvasに表示されないのは CORS が原因と思います。
応答ヘッダーAccess-Control-Allow-Headersも確認してください。

エラーメッセージは出ていません。

フレームワーク環境から一旦離れると、エラーは確認できます。

ローカル環境でクロスオリジンを手軽に確認するのに、hostname を localhost127.0.0.1 でアクセスしてみる手法があります。

以下のような簡単なサンプルコードを書き、確認しました。

[test.html]

HTML

1<body> 2 <img id="same" src="http://localhost:3000/t/test.jpg"> 3 <img id="cross" src="http://127.0.0.1:3000/t/test.jpg"> 4 <canvas id="view-canvas"></canvas> 5 <script> 6 let imagePath = document.getElementById("same").src; 7 let imagePathX = document.getElementById("cross").src; 8 let dstCanvas = document.getElementById("view-canvas"); 9 10 Object.assign( new Image(), { 11 src : imagePath, // imagePathX だとエラー 12 onload(event) { 13 let img = event.target; 14 let { width, height } = img; 15 Object.assign( dstCanvas, { width, height }) 16 .getContext("2d") 17 .drawImage( img, 0,0, width, height ); 18 19 console.log( dstCanvas.toDataURL() ); // imagePathX だとエラー 20 21 } 22 }); 23 </script> 24</body> 25<!-- 26以下のディレクトリ構成で確認 27 28public/ 29 t/ 30 test.html 31 test.jpg 32 33-->

{Canvas} の toDataURL() だけでなく、{CanvasRenderingContext2d} の getImageData() など、Canvas関連APIは クロスオリジンに対するセキュリティがあります。

追記ここまで)

ご質問コードに <script> が混入されているのが気になりますが、

モジュール化するのであれば、画像の baseUrl を引数で受け付ける関数を export するなどの方法を取ってはいかがでしょうか。Canvas(に表示するためのHTMLImageElement)を扱う *.html の PATH の変化に耐えられるはずです。

javascript

1// baseUrl は "/" で終わるディレクトリ情報とする 2export default ( baseUrl ) => ({ 3 4 methods:{ 5 draw() { 6 7 const src = baseUrl + "hoge.png" // 絶対パス化する。 8 9 } 10 } 11 12}); 13

投稿2020/05/02 09:18

編集2020/05/03 09:37
AkitoshiManabe

総合スコア5432

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

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

nyakorobin

2020/05/04 01:19

解決しました!! まず、CORSの設定を見直しました。 それでもできなかったので、その後、下記リンクのコードを参考にダウンロードをさせることができました。 toDataURL() メソッドはなぜか onclick イベント内だと画像も読み込めました。 ありがとうございました!! https://qiita.com/lookman/items/d93dd62a41f17a4d2de8
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問