2016-07-02 4 views
1

Iは、以下のタスクを達成しなければならない:画像をタイルで分割する方法は?

は、タイルに画像を分割し、各タイルの平均色を算出し、 は、その色のサーバからタイルを取り出し、そしてのフォトモザイクに 結果を合成します元の画像。

どのような戦略が最適でしょうか?私の頭に浮かぶ最初の解決策はキャンバスを使用することです。

答えて

1

ピクセルデータを取得し、タイルの手段を見つける簡単な方法です。コードでは、タイルの数で割ることができる次元を持たない画像のチェックがさらに必要になります。

var image = new Image(); 
image.src = ??? // the URL if the image is not from your domain you will have to move it to your server first 

// wait for image to load 
image.onload = function(){ 
    // create a canvas 
    var canvas = document.createElement("canvas"); 
    //set its size to match the image 
    canvas.width = this.width; 
    canvas.height = this.height; 
    var ctx = canvas.getContext("2d"); // get the 2d interface 
    // draw the image on the canvas 
    ctx.drawImage(this,0,0); 
    // get the tile size 
    var tileSizeX = Math.floor(this.width/10); 
    var tileSizeY = Math.floor(this.height/10); 
    var x,y; 
    // array to hold tile colours 
    var tileColours = []; 
    // for each tile 
    for(y = 0; y < this.height; y += tileSizeY){ 
     for(x = 0; x < this.width; x += tileSizeX){ 
      // get the pixel data 
      var imgData = ctx.getImageData(x,y,tileSizeX,tileSizeY); 
      var r,g,b,ind; 
      var i = tileSizeY * tileSizeX; // get pixel count 
      ind = r = g = b = 0; 
      // for each pixel (rgba 8 bits each) 
      while(i > 0){ 
       // sum the channels 
       r += imgData.data[ind++]; 
       g += imgData.data[ind++]; 
       b += imgData.data[ind++]; 
       ind ++; 
       i --; 
      } 
      i = ind /4; // get the count again 
      // calculate channel means 
      r /= i; 
      g /= i; 
      b /= i; 
      //store the tile coords and colour 
      tileColours[tileColours.length] = { 
       rgb : [r,g,b], 
       x : x, 
       y : y, 
      } 
     } 
     // all done now fetch the images for the found tiles. 
    } 
+0

'ctx.getImageData(X、Y、tileSizeX、tileSizeYは)'平均色を返す必要がありますか? – CodeYogi

+0

@ CodeYogi getImageDataはピクセルデータを配列として返しますが、データは処理されません。詳細については、https://developer.mozilla.org/en-US/docs/Web/API/CanvasRenderingContext2D/getImageData – Blindman67

+0

を参照してください。したがって、 'getImageData'は特定のタイルのピクセルデータを返し、' ind'変数はどうですか? – CodeYogi

0

私は(私はバックエンドからのタイル画像を取得していないです)、このためのソリューションを作成し

// first function call to create photomosaic 
    function photomosaic(image) { 

     // Dimensions of each tile 
     var tileWidth = TILE_WIDTH; 
     var tileHeight = TILE_HEIGHT; 

     //creating the canvas for photomosaic 
     var canvas = document.createElement('canvas'); 
     var context = canvas.getContext("2d"); 
     canvas.height = image.height; 
     canvas.width = image.width; 

     var imageData = context.getImageData(0, 0, image.width, image.height); 
     var pixels = imageData.data; 

     // Number of mosaic tiles 
     var numTileRows = image.width/tileWidth; 
     var numTileCols = image.height/tileHeight; 


     //canvas copy of image 
     var imageCanvas = document.createElement('canvas'); 
     var imageCanvasContext = canvas.getContext('2d'); 
     imageCanvas.height = image.height; 
     imageCanvas.width = image.width; 
     imageCanvasContext.drawImage(image, 0, 0); 


     //function for finding the average color 
     function averageColor(row, column) { 
      var blockSize = 1, // we can set how many pixels to skip 

       data, width, height, 
       i = -4, 
       length, 
       rgb = { 
        r: 0, 
        g: 0, 
        b: 0 
       }, 
       count = 0;   

      try { 
       data = imageCanvasContext.getImageData(column * TILE_WIDTH, row * TILE_HEIGHT, TILE_HEIGHT, TILE_WIDTH); 
      } catch (e) { 
       alert('Not happening this time!'); 
       return rgb; 
      } 

      length = data.data.length; 

      while ((i += blockSize * 4) < length) { 
       ++count; 
       rgb.r += data.data[i]; 
       rgb.g += data.data[i + 1]; 
       rgb.b += data.data[i + 2]; 
      } 

      // ~~ used to floor values 
      rgb.r = ~~(rgb.r/count); 
      rgb.g = ~~(rgb.g/count); 
      rgb.b = ~~(rgb.b/count); 

      return rgb; 

     } 

     // Loop through each tile 
     for (var r = 0; r < numTileRows; r++) { 
      for (var c = 0; c < numTileCols; c++) { 
       // Set the pixel values for each tile 
       var rgb = averageColor(r, c) 
       var red = rgb.r; 
       var green = rgb.g; 
       var blue = rgb.b; 

       // Loop through each tile pixel 
       for (var tr = 0; tr < tileHeight; tr++) { 
        for (var tc = 0; tc < tileWidth; tc++) { 

         // Calculate the true position of the tile pixel 
         var trueRow = (r * tileHeight) + tr; 
         var trueCol = (c * tileWidth) + tc; 

         // Calculate the position of the current pixel in the array 
         var pos = (trueRow * (imageData.width * 4)) + (trueCol * 4); 

         // Assign the colour to each pixel 
         pixels[pos + 0] = red; 
         pixels[pos + 1] = green; 
         pixels[pos + 2] = blue; 
         pixels[pos + 3] = 255; 
        }; 
       }; 
      }; 
     }; 

     // Draw image data to the canvas 
     context.putImageData(imageData, 0, 0); 
     return canvas; 
    } 

    function create() { 
     var image = document.getElementById('image'); 
     var canvas = photomosaic(image); 
     document.getElementById("output").appendChild(canvas); 
    }; 

DEMO:https://jsfiddle.net/gurinderiitr/sx735L5n/

0

は、ピクセルの色を読み取ることJIMP JavaScriptライブラリを使用してみてください画像を修正するために反転、正規化または同様の特性を使用する。タイルのサイズは右、単一のピクセルではないので

がjimpライブラリを見てください https://github.com/oliver-moran/jimp

関連する問題