Canvasを使用するWebワーカー

主なアイデア



ブラウザで画像処理をマルチスレッド化する方法を学習する過程で、多くの人は、 Web Workersの結果をキャンバスに表示する問題に直面しています。 これは主に、DOM要素をWeb Workerに渡すことができないという事実によるものです。 解決策はgetImageData()を使用することです 。 この記事では、別のストリームでぼかしフィルターを処理する例で、このテクノロジーを使用する特定の例を説明します。



このためには、 index.htmlfilter_worker.jsの 2つのファイルが必要です。



ページレイアウト



index.htmlには、現在のフィルター操作をパーセントで記録するぼかし半径とスパンを指定するためのフォームであるキャンバス要素を1つ配置する必要があります。

HTML
<!DOCTYPE html> <html> <head> <title>Web Worker</title> <style> #my_canvas { border: #00ff00 solid 1px; } </style> </head> <body> <form> <input type="text" id="radius" value="5" /> <input type="button" onclick="draw('my_canvas')" value="Draw" /> </form><br> <canvas id="my_canvas" width="200" height="200"></canvas><br> <span id="load_info"></span> </body> </html>
      
      









Javascript



キャンバスを構成し、Web Workerを呼び出すJavaScript関数を追加します。

Javascript
 //   var img = new Image(); img.src = "Malevich.jpg"; function draw(canvas_name) { //    Web Workers? if(!window.Worker) { return alert('    Web Workers!'); } //   var canvas = document.getElementById(canvas_name); var ctx = canvas.getContext("2d"); //   ctx.clearRect(0,0,canvas.width,canvas.height); ctx.drawImage(img,0,0,img.width,img.height,0,0,img.width,img.height); var worker = new Worker('filter_worker.js'); //   worker worker.postMessage({ //  ImageData  worker imagedata: ctx.getImageData(0, 0, canvas.width, canvas.height), width: canvas.width, height: canvas.height, radius: document.getElementById("radius").value }); worker.onmessage = function (event) { if (event.data.status === 'complite') { //   Image Data   canvas ctx.putImageData(event.data.imagedata,0,0); } else { //     ,     document.getElementById("load_info").innerHTML = event.data.progress + "%"; } } }
      
      









ウェブワーカー



ぼかしフィルターアルゴリズムは次のように機能します。現在のピクセルから特定の半径内にあるすべてのピクセルの色の合計の算術平均を求め、そこに出力カラーを書き込みます。

ウェブワーカー
 onmessage = function (event) { var imagedata = event.data.imagedata; var width = event.data.width; var height = event.data.height; var radius = event.data.radius; var sum_r, sum_g, sum_b, sum_a; //  ,     var scale = (radius * 2 + 1) * (radius * 2 + 1) var num_pixels = width * height; function getPixel(x, y) { if (x < 0) { x = 0; } if (y < 0) { y = 0; } if (x >= width) { x = width - 1; } if (y >= height) { y = height - 1; } var index = (y * width + x) * 4; return [ imagedata.data[index + 0], imagedata.data[index + 1], imagedata.data[index + 2], imagedata.data[index + 3], ]; } function setPixel(x, y, r, g, b, a) { var index = (y * width + x) * 4; imagedata.data[index + 0] = r; imagedata.data[index + 1] = g; imagedata.data[index + 2] = b; imagedata.data[index + 3] = a; } var lastprogress = 0; for (y = 0; y < height; y++) { for (x = 0; x < width; x++) { var progress = Math.round((((y * width) + height) / num_pixels) * 100); if (progress > lastprogress) { lastprogress = progress; postMessage({status: 'progress', progress: progress}); } sum_r = 0; sum_g = 0; sum_b = 0; sum_a = 0; for (var dy = -radius; dy <= radius; dy++) { for (var dx = -radius; dx <= radius; dx++) { var pixeldata = getPixel(x + dx, y + dy); sum_r += pixeldata[0]; sum_g += pixeldata[1]; sum_b += pixeldata[2]; sum_a += pixeldata[3]; } } //    (     //     setPixel( x, y, Math.round(sum_r / scale), Math.round(sum_g / scale), Math.round(sum_b / scale), Math.round(sum_a / scale) ); } } postMessage({status: 'complite', imagedata: imagedata}); }
      
      









結論:



この例に基づいて、Webページをフリーズさせない独自の画像処理スクリプトを作成できます。



All Articles