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

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

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

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

JavaScript

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

Q&A

1回答

3103閲覧

blobをcanvasに描画したい

Izumo1101

総合スコア49

canvas

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

JavaScript

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

0グッド

0クリップ

投稿2020/10/08 11:46

文字数制限ですべてが出せませんが、画像を読み込んで複数のcavasを利用し、トリミングするものを作ろうとしています。
ファイルを読み込んで描画→トリミングはうまくいきました。

javascript

1//一部ですが今回の質問部分でうまくいっている 2$("#upload_file").change(function() { 3 var file = this.files[0]; 4 if (!file.type.match(/^image/(png|jpeg|gif)$/)) return; 5 6 var image = new Image(); 7 console.log(image) 8 var reader = new FileReader(); 9 10 reader.onload = function(e) { 11 image.onload = function() { 12 13 var min_width = Math.min(this.width, max_canvas_size.width); 14 var min_height = Math.min(this.height, max_canvas_size.height); 15 var scale = Math.min(min_width / this.width, min_height / this.height); 16 var size = {width: this.width * scale, height: this.height * scale}; 17 18 resizeCanvas(size.width, size.height); 19 layer1Ctx.drawImage(image, 0, 0, size.width, size.height); 20 updateCanvas(); 21 22 $("#upload_button").attr('filename', file.name); 23 $("#upload_button").show(); 24 25 // load file on base buffer 26 base.width = this.width/3; 27 base.height = this.height/3; 28 baseCtx.drawImage(image, 0, 0,this.width/3,this.height/3); 29 } 30 image.src = e.target.result; 31 } 32 33 reader.readAsDataURL(file); 34 });

layer1に描画してほかのcanvasと連携していきます。

今回、すでに保持しているblobデータを描画したいと思っています。
blob:file:///665a1508-78d6-44a0-8020-cfbb47f6d1f3
↑imgUrlです
この描画の仕方が分かりません。
上を少し変えて、

javascript

1$('#testbtn').click(function(){ 2 //20201008 3 var imgUrl = window.opener.$('#kakusi').text(); 4 console.log(imgUrl + "画像のアドレス") 5 6 var image = new Image(); 7 image.src = imgUrl ; 8 console.log(image) 9 var reader = new FileReader(); 10 11 reader.onload = function(e) { 12 image.onload = function() { 13 14 var min_width = Math.min(this.width, max_canvas_size.width); 15 var min_height = Math.min(this.height, max_canvas_size.height); 16 var scale = Math.min(min_width / this.width, min_height / this.height); 17 var size = {width: this.width * scale, height: this.height * scale}; 18 19 resizeCanvas(size.width, size.height); 20 layer1Ctx.drawImage(image, 0, 0, size.width, size.height); 21 updateCanvas(); 22 23 24 // load file on base buffer 25 base.width = this.width/3; 26 base.height = this.height/3; 27 baseCtx.drawImage(image, 0, 0,this.width/3,this.height/3); 28 } 29 image.src = e.target.result; 30 } 31 32 reader.URL.createObjectURL(blob) ; 33 });

とimageにデータ情報を持たせようとしたのですがうまくいきません。
ネットでいただいた情報を参考にトライ&エラーでやっているので基本的なことが分かっていませんがどなたか教えてください。

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

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

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

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

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

kuma_kuma_

2020/10/08 12:19

> 今回、すでに保持しているblobデータを描画したいと思っています。 blobデータという事はバイナリのデータという事ですよね? これが画像データ(たとえばbmp形式)ならこうですと答えられるのですが なにか形式があるのですか? またそのblobデータ自体どの様の作成されたものなのですか?
Izumo1101

2020/10/08 12:28

ありがとうございます。 このblobデータ自体は、先に var blobUrl = window.URL.createObjectURL( fileList[i] ) ; という形でfor文で廻して取得したものになります。 そのうちの対象のsrcを#kakusiに格納しているのでそれを呼び出す形となります。 元々のデータの形式はjpg,png等の画像イメージです。
m.ts10806

2020/10/08 12:34

ブラウザ開発ツールのコンソールにエラー出てませんか?
Izumo1101

2020/10/08 12:42

デベロッパツールのエラーは Uncaught TypeError: Cannot read property 'createObjectURL' of undefined とありますが、layer1に描画されていないので次のcanvasにcreateできないよ、という意味だととらえております。 ご提示の参考サイトですが、3つ目の内容が近いのですが、それはすでに質問上部の「うまくいっている」記述でできている内容となります。
m.ts10806

2020/10/08 12:46 編集

blobという変数が定義もなくいきなり利用されているのも気になりますが、 reader.URL.createObjectURL()がonloadの外にあることでreaderが確立する前に読みに行こうとしているようにも見えます。
Izumo1101

2020/10/08 12:48

ほんとだw定義もしていないものがいきなり登場していますね。 最終行 reader.URL.createObjectURL(blob) ; をコメントアウトして試したりもしましたが、こちらはエラーも吐かずにコメントは出る状態です。つまり純粋に描画自体ができていないように思われます。
m.ts10806

2020/10/08 12:49

手元で試せないので「やってみてください」程度で申し訳ないですが、 変数blobに想定の情報を入れたうえで image.onloadの最後に reader.URL.createObjectURL() ; を入れるとどうですか?
Izumo1101

2020/10/08 12:55

・・・・・ baseCtx.drawImage(image, 0, 0,this.width/3,this.height/3); reader.URL.createObjectURL(imgUrl) ; } image.src = e.target.result; } }); imgUrl・image、()等引数もいろいろ試しましたがエラーは吐きませんが描画もしない状態です。コメントは出ているので走っていはいると思います。 なんか支離滅裂で申し訳ない・・・
kuma_kuma_

2020/10/08 13:23

うーん。質問者様。blobと書かれると形式不明のバイナリファイルと考えるしかないんですね。 例えば 1. <canvas>に描写した画像情報を内部で保留。別の<canvas>に描写 2. 画像ファイルとして別URLに存在するファイルを<canvas>に描写 3. <canvas>に描写された内容を画像ファイルとしてダウンロード 4. SVGファイル(座標、色等文字列で書かれた画像情報)を読み込んで<canvas>に描写 5. <canvas>からSVGファイル形式で画像情報を保存 なら具体的な形式がわかって答えられるのですが... 6. 画像に行うトリミング、フィルタ情報が外部ファイル(バッファ)に存在しそれを適応させたい。 だとまた話が変わるのですが...
Izumo1101

2020/10/08 13:36

自分でもきっと質問自体に不備があるなと感じてはいるのですが・・・申し訳ない。 2が近いでしょうか。 親(別)ウィンドウで、フォルダ内にある複数の画像をサムネイル化し表示させ、サムネイルクリックでbodyに動的に挿入するスクリプトを書いています。 for( var i=0,l=fileList.length; l>i; i++ ) { // Blob URLの作成 var blobUrl = window.URL.createObjectURL( fileList[i] ) ; $('.target').append('<a><img id="' + i + '" class="prepep" src="' + blobUrl + '" style="width:5vw"></a>'); } 任意のタイミングでクリック動作で画像として記述するため(numは変数) var new_node = $('<img class="element" id="panPinchElm' + num + '" src="' + src + '" style="height:100px; width:auto;">'); と定義していまして、これ自体は想定の動きをします。 この入手したBlobUrlを生かして子ウィンドウ内でトリミングしたいというのが今回の趣旨。子ウィンドウで再度画像を呼び出せば普通に描画できますが、そのステップを省いてすでに手元にある情報で対処したいということなんです。。。。blob情報からimgとして挿入できるならcanvasにも誘導できるのでは、ということです。
kuma_kuma_

2020/10/08 14:16 編集

createObjectURLで画像化したblobは一度表示されると使えなくなります。 (先のURLに解説があったのですが...) またcreateObjectURLのブラウザ対応も廃止だそうです。 もし目的の事をされるなら<canvas>タグを画像(jpeg or png)に変換してそれをBASE64形式の文字列へ 変換し https://javascript.programmer-reference.com/js-canvas-base64/ URLに指定する事で内部的に画像データを保留できます。 あとは選ばれた画像のBASE64形式の文字列から<canvas>へ画像を展開 https://javascript.programmer-reference.com/js-base64-canvas/ すればよいのでは? ローカルで試す場合 img.crossOrigin = 'Anonymous'; というテクニックが必要となります。 https://www.nabeen.be/post/2019/11/to-data-url-cross-origin/
kairi003

2020/10/08 20:21

>> Uncaught TypeError: Cannot read property 'createObjectURL' of undefined が二つ目の方で出てるならreader.URLがundefinedなだけだと思うんですが… blob->URLはFileReaderでなくURL.createObjectURLで同期的に取れます
guest

回答1

0

Fileオブジェクトは Blobオブジェクトの派生であるため、URL.createObjectURL() の引数には File オブジェクトを渡すことができます。

CODEPEN 画像のアップロードプレビュー で実装したものを回答したことがあります。

  • L1-3 : キャッシュ
  • L7 : メモリ解放(キャッシュした 全BlobURL が対象)
  • L29 : Fileオブジェクトから BlobURL を取得しキャッシュする。

Canvas に描画する場合、Image(HTMLImageElement)を描画すると思いますが、Image.src に blobUrl を渡して、load イベントを待ち、描画処理する感じでしょうか。

Web アプリケーションからのファイルの使用 のページにある「オブジェクト URL を利用する」セクションは必読です。

URL.revokeObjectURL() を呼ぶまでメモリ上に存在し続けるので、取扱には、キャッシュするなどの BlobURLの管理が必要になります。


修正コメント内で「createObjectURL() が使えなくなる(らしい)」との意見がありましたので、検索してみると、video に関連する MediaStream に限って言及されているように思いました。

ご質問のコードでは file.type から 画像ファイルのみを切り分けており、
video ではなく「画像」ですので、継続して使えるかもしれませんが、「しばらくの間、開発者コンソールに表示する」というベンダの対応に注意する必要があります。

投稿2020/10/08 23:52

AkitoshiManabe

総合スコア5432

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

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

Izumo1101

2020/10/23 14:29

ご回答ありがとうございます。ぱっと見、私の求めている内容だと感じましたのでご教示いただいた内容を検証させてください。非常に有意義な内容だと感じました。ちょっと潜ってみます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだベストアンサーが選ばれていません

会員登録して回答してみよう

アカウントをお持ちの方は

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問