質問編集履歴

2

ブログラムの修正

2017/12/22 03:15

投稿

west826
west826

スコア14

test CHANGED
File without changes
test CHANGED
@@ -122,7 +122,7 @@
122
122
 
123
123
  <button onClick="grayscale()" id="gray">モノクロ</button>
124
124
 
125
- <button onClick="heatmap()">疑似カ</button>
125
+ <button onClick="outline()">アウトイン</button>
126
126
 
127
127
 
128
128
 
@@ -190,7 +190,7 @@
190
190
 
191
191
  };
192
192
 
193
- //疑似カ
193
+ //アウトイン
194
194
 
195
195
  function heatmap(){
196
196
 
@@ -278,7 +278,7 @@
278
278
 
279
279
 
280
280
 
281
- //疑似カ
281
+ //アウトイン
282
282
 
283
283
  function heatmap1(){
284
284
 

1

コードの追加

2017/12/22 03:15

投稿

west826
west826

スコア14

test CHANGED
File without changes
test CHANGED
@@ -52,6 +52,542 @@
52
52
 
53
53
 
54
54
 
55
+ ```HTML
56
+
57
+ <!DOCTYPE html>
58
+
59
+ <html lang="ja">
60
+
61
+ <head>
62
+
63
+ <meta charset="utf-8">
64
+
65
+ <title>test</title>
66
+
67
+
68
+
69
+ <style type="text/css">
70
+
71
+ #v{
72
+
73
+ display:none;
74
+
75
+ }
76
+
77
+ #screen{
78
+
79
+ width:480px;
80
+
81
+ height:270px;
82
+
83
+ background-color:#000000;
84
+
85
+ }
86
+
87
+ button{
88
+
89
+ width:100px;
90
+
91
+ height:50px;
92
+
93
+ }
94
+
95
+
96
+
97
+ </style>
98
+
99
+ </head>
100
+
101
+
102
+
103
+ <body>
104
+
105
+ <video controls id="v" width="480" height="270">
106
+
107
+ <source src="movie.mp4" width="480" height="270">
108
+
109
+ </video>
110
+
111
+ <div id="screen">
112
+
113
+ <canvas id="c" width="480" height="270"></canvas>
114
+
115
+ </div>
116
+
117
+ <button onClick="playVideo()">play/stop</button>
118
+
119
+ <button onClick="restart()">restart</button>
120
+
121
+ <button onClick="no()" id="gray">なし</button>
122
+
123
+ <button onClick="grayscale()" id="gray">モノクロ</button>
124
+
125
+ <button onClick="heatmap()">疑似カラー</button>
126
+
127
+
128
+
129
+ <input id="color" type="color" value="#ff0000" />
130
+
131
+ <input id="distance" type="number" value="10" />
132
+
133
+
134
+
135
+ <script type="text/javascript">
136
+
137
+
138
+
139
+ //play/stopボタンの設定
140
+
141
+ function playVideo(){
142
+
143
+ var video = document.getElementById("v");
144
+
145
+ if(video.paused){
146
+
147
+ video.play();
148
+
149
+ }else{
150
+
151
+ video.pause();
152
+
153
+ }
154
+
155
+ setInterval(function(){
156
+
157
+ var canvas = document.getElementById("c");
158
+
159
+ canvas.getContext("2d").drawImage(video, 0, 0, 480, 270);
160
+
161
+ }, 1000/30);
162
+
163
+ }
164
+
165
+ //restartボタンの設定
166
+
167
+ function restart() {
168
+
169
+ var video = document.getElementById("v");
170
+
171
+ video.currentTime = 0;
172
+
173
+ }
174
+
175
+
176
+
177
+
178
+
179
+ var reqId = null;
180
+
181
+
182
+
183
+ //モノクロ
184
+
185
+ function grayscale(){
186
+
187
+ cancelRender();
188
+
189
+ grayFilter();
190
+
191
+ };
192
+
193
+ //疑似カラー
194
+
195
+ function heatmap(){
196
+
197
+ cancelRender();
198
+
199
+ heatmap1();
200
+
201
+ };
202
+
203
+
204
+
205
+ function cancelRender() {
206
+
207
+ if(reqId) {
208
+
209
+ cancelAnimationFrame(reqId);
210
+
211
+ }
212
+
213
+ }
214
+
215
+
216
+
217
+ //モノクロ
218
+
219
+ function grayFilter(){
220
+
221
+ loop();
222
+
223
+
224
+
225
+ function loop(){
226
+
227
+ monokuro();
228
+
229
+ reqId = requestAnimationFrame(loop);
230
+
231
+ };
232
+
233
+
234
+
235
+ // 描画内容に対して、式を当てはめながらrgbの値を計算する。
236
+
237
+ function monokuro(){
238
+
239
+ // 対象のCanvasを取得し、contextも取得する。
240
+
241
+ var canvas = document.getElementById("c");
242
+
243
+ var context = canvas.getContext("2d");
244
+
245
+ video = document.getElementById("v");
246
+
247
+
248
+
249
+ // Canvasから描画内容を保持するimageDataを取得する。
250
+
251
+ var imageData = context.getImageData(0, 0, canvas.width, canvas.height);
252
+
253
+
254
+
255
+ var d = imageData.data;
256
+
257
+ for (var i = 0; i < d.length; i+=4) {
258
+
259
+ var g = d[i] * 0.2126 + d[i+1] * 0.7152 + d[i+2] * 0.0722;
260
+
261
+ d[i] = d[i+1] = d[i+2] = g;
262
+
263
+ // d[i+3]に格納されたα値は変更しない
264
+
265
+ }
266
+
267
+
268
+
269
+
270
+
271
+ // 計算結果でCanvasの表示内容を更新する。
272
+
273
+ context.putImageData(imageData, 0, 0);
274
+
275
+ }
276
+
277
+ }
278
+
279
+
280
+
281
+ //疑似カラー
282
+
283
+ function heatmap1(){
284
+
285
+ (function () {
286
+
287
+ //Canvasの準備
288
+
289
+ var canvas = document.getElementById("c");
290
+
291
+ var context = canvas.getContext("2d");
292
+
293
+ var video = document.getElementById("v");
294
+
295
+
296
+
297
+ // 境界線とする閾値
298
+
299
+ var outlineColor = {r: 255, g: 0, b: 0},
300
+
301
+ complementaryColor = {r: 0, g: 255, b: 255},
302
+
303
+ colorDistance = 10;
304
+
305
+
306
+
307
+ draw();
308
+
309
+
310
+
311
+
312
+
313
+ // videoの映像をcanvasに描画する
314
+
315
+ function draw() {
316
+
317
+ //context.drawImage(video, 0, 0, canvas.width, canvas.height);
318
+
319
+ // ここでアウトライン処理をする
320
+
321
+ outline();
322
+
323
+ requestAnimationFrame(draw);
324
+
325
+ };
326
+
327
+
328
+
329
+ // 境界線とする閾値
330
+
331
+ var outlineColor = {r: 255, g: 0, b: 0},
332
+
333
+ complementaryColor = {r: 0, g: 255, b: 255},
334
+
335
+ colorDistance = 10;
336
+
337
+
338
+
339
+ // アウトライン処理
340
+
341
+ function outline() {
342
+
343
+ var imageData = context.getImageData(0, 0, canvas.width, canvas.height),
344
+
345
+ data = imageData.data;
346
+
347
+
348
+
349
+ // dataはUint8ClampedArray
350
+
351
+ // 長さはcanvasの width * height * 4(r,g,b,a)
352
+
353
+ // 先頭から、一番左上のピクセルのr,g,b,aの値が順に入っており、
354
+
355
+ // 右隣のピクセルのr,g,b,aの値が続く
356
+
357
+ // n から n+4 までが1つのピクセルの情報となる
358
+
359
+
360
+
361
+ var currentOutlineColor = outlineColor;
362
+
363
+
364
+
365
+ for (var i = 0, l = data.length; i < l; i += 4) {
366
+
367
+
368
+
369
+ // この条件の時、currentは右端の色、nextは1px下の段の左端の色になるので透明にしてスキップする
370
+
371
+ if ((i / 4 + 1) % canvas.width === 0) {
372
+
373
+ data[i + 3] = 0;
374
+
375
+ continue;
376
+
377
+ }
378
+
379
+
380
+
381
+ // 段が変わったら色を変える
382
+
383
+ // 一段ずつoutlineColorからcomplementaryColorにグラデーションにする
384
+
385
+ if ((i / 4) % canvas.width === 0) {
386
+
387
+ var row = (i / 4) / canvas.width,
388
+
389
+ r = (outlineColor.r - complementaryColor.r) / canvas.height,
390
+
391
+ g = (outlineColor.g - complementaryColor.g) / canvas.height,
392
+
393
+ b = (outlineColor.b - complementaryColor.b) / canvas.height;
394
+
395
+
396
+
397
+ currentOutlineColor = {
398
+
399
+ r: outlineColor.r - (r * row),
400
+
401
+ g: outlineColor.g - (g * row),
402
+
403
+ b: outlineColor.b - (b * row)
404
+
405
+ };
406
+
407
+ }
408
+
409
+
410
+
411
+ var currentIndex = i,
412
+
413
+ nextIndex = currentIndex + 4,
414
+
415
+ underIndex = currentIndex + (canvas.width * 4),
416
+
417
+ // チェックするピクセルの色
418
+
419
+ current = {
420
+
421
+ r: data[currentIndex],
422
+
423
+ g: data[currentIndex + 1],
424
+
425
+ b: data[currentIndex + 2]
426
+
427
+ },
428
+
429
+ // 右隣の色
430
+
431
+ next = {
432
+
433
+ r: data[nextIndex],
434
+
435
+ g: data[nextIndex + 1],
436
+
437
+ b: data[nextIndex + 2]
438
+
439
+ },
440
+
441
+ // 下の色
442
+
443
+ under = {
444
+
445
+ r: data[underIndex],
446
+
447
+ g: data[underIndex + 1],
448
+
449
+ b: data[underIndex + 2]
450
+
451
+ };
452
+
453
+
454
+
455
+ // 現在のピクセルと右隣、下の色の三次元空間上の距離を閾値と比較する
456
+
457
+ // 閾値より大きい(色が遠い)場合、境界線とみなしそのピクセルをcurrentOutlineColorに変更
458
+
459
+ // 閾値より小さい(色が近い)場合、そのピクセルを消す
460
+
461
+ if (getColorDistance(current, next) > colorDistance || getColorDistance(current, under) > colorDistance) {
462
+
463
+ data[i] = currentOutlineColor.r;
464
+
465
+ data[i + 1] = currentOutlineColor.g;
466
+
467
+ data[i + 2] = currentOutlineColor.b;
468
+
469
+ } else {
470
+
471
+ // alpha値を0にすることで見えなくする
472
+
473
+ data[i + 3] = 0;
474
+
475
+ }
476
+
477
+ }
478
+
479
+
480
+
481
+ // 書き換えたdataをimageDataにもどし、描画する
482
+
483
+ imageData.data = data;
484
+
485
+ context.putImageData(imageData, 0, 0);
486
+
487
+ };
488
+
489
+
490
+
491
+ // r,g,bというkeyを持ったobjectが第一引数と第二引数に渡される想定
492
+
493
+ function getColorDistance(rgb1, rgb2) {
494
+
495
+ // 三次元空間の距離が返る
496
+
497
+ return Math.sqrt(
498
+
499
+ Math.pow((rgb1.r - rgb2.r), 2) +
500
+
501
+ Math.pow((rgb1.g - rgb2.g), 2) +
502
+
503
+ Math.pow((rgb1.b - rgb2.b), 2)
504
+
505
+ );
506
+
507
+ };
508
+
509
+
510
+
511
+ var color = document.getElementById('color');
512
+
513
+ color.addEventListener('change', function () {
514
+
515
+ // フォームの値は16進カラーコードなのでrgb値に変換する
516
+
517
+ outlineColor = color2rgb(this.value);
518
+
519
+ complementaryColor = getComplementaryColor(outlineColor);
520
+
521
+ });
522
+
523
+
524
+
525
+ var color2rgb = function (color) {
526
+
527
+ color = color.replace(/^#/, '');
528
+
529
+ return {
530
+
531
+ r: parseInt(color.substr(0, 2), 16),
532
+
533
+ g: parseInt(color.substr(2, 2), 16),
534
+
535
+ b: parseInt(color.substr(4, 2), 16)
536
+
537
+ };
538
+
539
+ };
540
+
541
+
542
+
543
+ // 補色の計算
544
+
545
+ var getComplementaryColor = function (rgb) {
546
+
547
+ var max = Math.max(rgb.r, rgb.g, rgb.b),
548
+
549
+ min = Math.min(rgb.r, rgb.g, rgb.b),
550
+
551
+ sum = max + min;
552
+
553
+ return {
554
+
555
+ r: sum - rgb.r,
556
+
557
+ g: sum - rgb.g,
558
+
559
+ b: sum - rgb.b
560
+
561
+ };
562
+
563
+ };
564
+
565
+
566
+
567
+ var distance = document.getElementById('distance');
568
+
569
+ distance.style.textAlign = 'right';
570
+
571
+ distance.addEventListener('change', function () {
572
+
573
+ colorDistance = this.value;
574
+
575
+ });
576
+
577
+ })();
578
+
579
+ }
580
+
581
+ </script>
582
+
583
+ </body>
584
+
585
+ </html>
586
+
587
+
588
+
589
+ ```
590
+
55
591
 
56
592
 
57
593
  ---