回答編集履歴

2

追記&訂正

2019/08/26 05:10

投稿

退会済みユーザー
test CHANGED
@@ -32,7 +32,7 @@
32
32
 
33
33
 
34
34
 
35
- 画像の読み込みにかかる時間が画像のサイズなどによって異なるので、load イベント発生のタイミングは不定となりますが、それに対応するために最後の load イベントの発生を待って、そのイベントリスナで drawImage で順番を守って canvas に書き込むのがよさそうです。
35
+ 画像の読み込みにかかる時間が画像のサイズなどによって異なるので、load イベント発生の順番は不定となりますが、それに対応するために最後の load イベントの発生を待って、そのイベントリスナで希望する順番に各 image を drawImage で canvas に書き込むのがよさそうです。
36
36
 
37
37
 
38
38
 

1

追記

2019/08/26 05:10

投稿

退会済みユーザー
test CHANGED
@@ -9,3 +9,225 @@
9
9
 
10
10
 
11
11
  不明な点があれば聞いてください。
12
+
13
+
14
+
15
+ **【追記】**
16
+
17
+
18
+
19
+ 下の 2019/08/26 13:14 の私のコメントに「もう少し考えてみました・・・回答欄にそのあたりを追記しておきます」と書きましたが、それを以下に追記します。
20
+
21
+
22
+
23
+ コメント欄に「複数の画像を扱うということが何か関係してる」と書きましたがそんなことはなくて、ごく単純に一枚だけ扱った場合でも canvas.toDataURL("image/png"); を image.onload のリスナの外に記述すると Data Url は取得できません。
24
+
25
+
26
+
27
+ 逆に言うと、一枚でも複数でも image.onload のリスナの中に canvas.toDataURL("image/png"); を書けば Data Url は取得できます。もちろん setTimeout で待つ必要は有りません。
28
+
29
+
30
+
31
+ 複数の画像の場合、複数の image.onload イベントに複数のリスナがアタッチされますが、そのリスナにどのように canvas.toDataURL("image/png"); を記述するかが考えどころです。
32
+
33
+
34
+
35
+ 画像の読み込みにかかる時間が画像のサイズなどによって異なるので、load イベント発生のタイミングは不定となりますが、それに対応するために最後の load イベントの発生を待って、そのイベントリスナで drawImage で順番を守って canvas に書き込むのがよさそうです。
36
+
37
+
38
+
39
+ そうすれば、そのリスナで canvas に書き込んだ後、同じリスナ内で canvas.toDataURL("image/png"); によって Data Url を取得できます。
40
+
41
+
42
+
43
+ 検証に使ったコードを以下にアップしておきます。元の画像は 226px x 150px の .png または .jpg 画像です。(ASP.NET のページを利用していますが、そこは本題とは関係ないので気にしないでください)
44
+
45
+
46
+
47
+ ```
48
+
49
+ <%@ Page Language="C#" AutoEventWireup="true"
50
+
51
+ CodeFile="0076-Canvas.aspx.cs" Inherits="_0076_Canvas" %>
52
+
53
+
54
+
55
+ <!DOCTYPE html>
56
+
57
+
58
+
59
+ <html xmlns="http://www.w3.org/1999/xhtml">
60
+
61
+ <head runat="server">
62
+
63
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
64
+
65
+ <title></title>
66
+
67
+ <script type="text/javascript">
68
+
69
+ window.onload = function () {
70
+
71
+ var srcs = [
72
+
73
+ "/Images/image1.png",
74
+
75
+ "/Images/image2.jpg",
76
+
77
+ "/Images/image3.jpg",
78
+
79
+ "/Images/image4.jpg",
80
+
81
+ "/Images/image5.jpg"
82
+
83
+ ];
84
+
85
+
86
+
87
+ var canvas = document.getElementById('mycanvas');
88
+
89
+ var context = canvas.getContext('2d');
90
+
91
+
92
+
93
+
94
+
95
+ // 単純に一枚の画像の場合
96
+
97
+ // これは OK だが、canvas.toDataURL("image/png") をリスナの外に出すとダメ
98
+
99
+ //var image = new Image();
100
+
101
+ //image.src = "/Images/image1.png";
102
+
103
+ //image.onload = function () {
104
+
105
+ // context.drawImage(image, 0, 0);
106
+
107
+ // var result = canvas.toDataURL("image/png");
108
+
109
+ // document.getElementById("image1").src = result;
110
+
111
+ //};
112
+
113
+
114
+
115
+
116
+
117
+ // 質問者さんのコードと似たような感じにしてみましたが、load イベントの発生タイミング
118
+
119
+ // は i の順番にならず、canvas に描かれる順番が保証されないのでダメ
120
+
121
+ //var y = 0;
122
+
123
+ //for (let i = 0; i < srcs.length; i++) {
124
+
125
+ // let image = new Image();
126
+
127
+ // image.src = srcs[i];
128
+
129
+ // image.onload = function () {
130
+
131
+ // context.drawImage(image, 0, y);
132
+
133
+ // y += 150;
134
+
135
+ // }
136
+
137
+ //}
138
+
139
+
140
+
141
+
142
+
143
+ // canvas に描かれる順番を保証するには以下のようにするのがよさそう。そうすれば
144
+
145
+ // リスナの中に canvas.toDataURL("image/png"); を記述でき Data Url が取得できる
146
+
147
+ var images = [];
148
+
149
+ var loadCount = 0;
150
+
151
+ for (let i = 0; i < srcs.length; i++)
152
+
153
+ {
154
+
155
+ images[i] = new Image();
156
+
157
+ images[i].src = srcs[i];
158
+
159
+ images[i].onload = function () {
160
+
161
+ loadCount++;
162
+
163
+ if (loadCount == images.length)
164
+
165
+ {
166
+
167
+ for (let j = 0; j < images.length; j++)
168
+
169
+ {
170
+
171
+ context.drawImage(images[j], 0, j * 150);
172
+
173
+ }
174
+
175
+
176
+
177
+ // image.onload のリスナの中でないと Data Url が取得できない
178
+
179
+ var result = canvas.toDataURL("image/png");
180
+
181
+ document.getElementById("image1").src = result;
182
+
183
+ }
184
+
185
+ };
186
+
187
+ }
188
+
189
+
190
+
191
+ // ここではダメ。Data Url は取得できない
192
+
193
+ //var result = canvas.toDataURL("image/png");
194
+
195
+ //document.getElementById("image1").src = result;
196
+
197
+ }
198
+
199
+ </script>
200
+
201
+ </head>
202
+
203
+ <body>
204
+
205
+ <form id="form1" runat="server">
206
+
207
+ <div style="float: right;">
208
+
209
+ <canvas id="mycanvas" width="266" height="750"></canvas>
210
+
211
+ </div>
212
+
213
+ <div>
214
+
215
+ <img id="image1" alt="" />
216
+
217
+ </div>
218
+
219
+ </form>
220
+
221
+ </body>
222
+
223
+ </html>
224
+
225
+ ```
226
+
227
+
228
+
229
+ 結果は以下のようになります。
230
+
231
+
232
+
233
+ ![イメージ説明](a4c1cd0909fc47dc73ae5fd994bb9638.jpeg)