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

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

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

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

Q&A

6回答

12570閲覧

JavaScriptのImageオブジェクトの画像サイズ取得

退会済みユーザー

退会済みユーザー

総合スコア0

JavaScript

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

jQuery

jQueryは、JavaScriptライブラリのひとつです。 簡単な記述で、JavaScriptコードを実行できるように設計されています。 2006年1月に、ジョン・レシグが発表しました。 jQueryは独特の記述法を用いており、機能のほとんどは「$関数」や「jQueryオブジェクト」のメソッドとして定義されています。

0グッド

3クリップ

投稿2015/12/01 08:53

JavaScript(jQuery)で下記のようにImageオブジェクトを生成し、画像を読み込んだあとに、縦横サイズを取得し、その値を次の処理で使いたいのですが、画像の読込は非同期のため、うまくサイズを取得できません。

連続して処理を行いたいので、Imageオブジェクトのonloadイベントを使わず、読込完了を待ってから、サイズを取得できる実装例がありましたらお願いします。

javascript

1var image = new Image(); 2var width; 3var height; 4 5// onloadは使わない 6//image.onload = function(){ 7// width = image.width; 8// height = image.height; 9//}; 10 11image.src = 'hoge.jpg'; // 読み込む画像 12 13width = image.width; // これらは取得できない 14height = image.height; 15 16// 次に処理するもの 17alert(width+'x'+height); 18 :

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

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

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

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

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

guest

回答6

0

JSではその処理はできないと思います。
そもそもシングルスレッドなので処理を待ってしまうと画面がフリーズしてまうので。

なので、JSでは非同期で処理を行うのが基本です。
逆に非同期でやらない理由はなんででしょうか?

ちなみに並列っぽく処理を書きたい、ということであれば
jQueryのdeferredや、比較的新しいブラウザをターゲットにできるならPromiseあたりで調べてみると答えが見つかると思います。

投稿2015/12/01 09:26

edo_m18

総合スコア2283

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

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

0

setInterval()naturalWidth, naturalHeight を監視すれば原理的には可能です。
が、addEventListenerload を監視したほうが素直ですし、負荷も小さいと思います。

(2015/12/01 19:56追記)
load イベントのサンプルを追記しました。

JavaScript

1'use strict'; 2(function () { 3 function handleLoad (event) { 4 var img = event.target; 5 6 img.removeEventListener('load', this, false); 7 this.complete(img); 8 } 9 10 function next (img) { 11 console.log(img.width, img.height); 12 } 13 14 function main () { 15 var srcList = ['sample1.jpg', 'sample2.jpg', 'sample3.jpg'], 16 listener = {handleEvent: handleLoad, complete: next}; 17 18 for (var i = 0, l = srcList.length, img; i < l; ++i) { 19 img = new Image; 20 img.addEventListener('load', listener, false); 21 img.src = srcList[i]; 22 } 23 } 24 25 main(); 26}());

(2015/12/02 07:59追記)
ひょっとして実行順も保証したいという意味だったでしょうか。
実行順を保証するコードを追記しました。

JavaScript

1'use strict'; 2(function () { 3 function handleLoad (event) { 4 var img = event.target, 5 imgList = this.imgList, 6 srcList = this.srcList; 7 8 img.removeEventListener('load', this, false); 9 imgList[srcList.indexOf(img.getAttribute('src'))] = img; 10 11 if (Object.keys(imgList).length === srcList.length) { 12 this.complete(imgList); 13 } 14 } 15 16 function next (imgList) { 17 for (var i = 0, l = imgList.length, img; i < l; ++i) { 18 img = imgList[i]; 19 console.log(img, img.width, img.height); 20 } 21 } 22 23 function main () { 24 var srcList = ['sample1.jpg', 'sample2.jpg', 'sample3.jpg'], 25 listener = { 26 handleEvent: handleLoad, 27 srcList: srcList, 28 imgList: [], 29 complete: next 30 }; 31 32 for (var i = 0, l = srcList.length, img; i < l; ++i) { 33 img = new Image; 34 img.addEventListener('load', listener, false); 35 img.src = srcList[i]; 36 } 37 } 38 39 main(); 40}());

投稿2015/12/01 09:47

編集2015/12/01 23:40
think49

総合スコア18162

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

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

think49

2015/12/01 23:00

実行順を保証するコードを追記しました。
guest

0

onloadを使わずに画像のロード完了をチェックするには、setIntervalやsetTimeoutを使うのが一般的かと思います。「連続して処理」する内容にもよりますが、自分がよく使う方法を以下に記します。

JavaScript

1var img = new Image(); 2img.src = './images/sample.jpg'; 3 4(function(){ 5 if(!img.naturalWidth){ //naturalWidthがセットされていなければ 6 setTimeout(arguments.callee); //次のフレームで再度チェック 7 return; //以下の処理を停止 8 } 9 10 //naturalWidthがセットされていれば以下の処理を実行 11 alert(img.naturalWidth + '/' + img.naturalHeight); 12})(); 13

onloadイベントは古いIEでキャッシュを読んだ時に発生しないことがあったり、completeはsrcが空の場合の値がブラウザごとに違ったりするので、自分もonloadイベントを使わないことが多いです。

ご参考まで。

投稿2015/12/09 05:56

miwakazuo

総合スコア52

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

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

0

画像ロード、処理
画像ロード、処理
画像ロード、処理
とし、画像は読み込み順が前提にあり、画像1のx、y
画像2のx、y
、、、
として、画像1の処理が終わる前に
画像2の処理がかんりょうしてはまずい、

というばあいは、つかいたくないだろうけど、onload
をつかう、onload の中で、キューに登録し、画像の数分きゅーが溜まってないなら何もしない。
キューの長さとonload イベント実行回数が等しいとき、つまり最後のonload イベント処理内で、
キューを画像の読み込み順序でソートして先頭から読み解けば期待する順序のある画像読み込みと
画像のーx、yを扱った処理が可能です。
キューに格納する項目は、画像の番号、画像のxとy
画像の番号で昇順ソートすることで、画像の読み込み順序を同期化したとみなせますね。

投稿2015/12/01 16:41

ipadcaron

総合スコア1693

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

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

0

edo_m18さんのおっしゃるように基本的には非同期のコーディングを書くのが自然かなと思います。
promiseやdefferedを使わない場合は、以下のようなコードで実現できると思います。
動かしていないので、参考までですが、コードをのせておきます。

JavaScript

1var images = ['1.png','2.png','3.png'] ; // ロードする画像名 2var sizeData = {}; // 画像のサイズ情報 3 4// 全ての画像がロードされた時に呼ばれる処理 5var onAllImageLoaded = function(){ 6 console.log(sizeData) ; 7} ; 8 9// 全画像分ループ 10jQuery.each(images,function(i,imageName){ 11 var image = new Image() ; 12 // 画像がロードされた場合のコールバック 13 image.onload = function(){ 14 sizeData[imageName] = { 15 w:image.width, 16 h:image.height 17 } ; 18 19 // 全画像のsizeDataがあるか毎回チェック 20 if(Object.keys(sizeData).length == images.length){ 21 // 全てロードされていたら、コールバックを実行 22 onAllImageLoaded() ; 23 } 24 } ; 25 image.src = imageName ; 26}) ;

投稿2015/12/01 10:32

sekitaka_1214

総合スコア509

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

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

0

あまりきちんと動作確認していませんが。

javascript

1while(!image.complete); // 注意:画像が存在しないとたぶん無限ループします 2width = image.width; 3height = image.height;

投稿2015/12/01 09:53

Lhankor_Mhy

総合スコア36074

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

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

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

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

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

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問