如何在瓷砖中划分图像?

时间:2016-07-02 05:22:28

标签: javascript html5 image web html5-canvas

我必须完成以下任务:

  

将图像划分为图块,计算每个图块的平均颜色,   从服务器获取该颜色的图块,并合成   结果成为原始图像的照片马赛克。

什么是最好的策略?我想到的第一个解决方案是使用画布。

3 个答案:

答案 0 :(得分: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.
    }

答案 1 :(得分: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);
  };

样本:https://jsfiddle.net/gurinderiitr/sx735L5n/

答案 2 :(得分:0)

尝试使用JIMP javascript库读取像素颜色,并使用反转,规范化或类似属性来修改图像。

查看jimp库 https://github.com/oliver-moran/jimp