-1

So you can pixelate an image by drawing it on canvas like this:

/* css */
.pixelate {
  image-rendering: optimizeSpeed;
  image-rendering: -moz-crisp-edges;
  image-rendering: -o-crisp-edges;
  image-rendering: -webkit-crisp-edges;
  image-rendering: crisp-edges;
  image-rendering: -webkit-optimize-contrast;
  image-rendering: pixelated;
  -ms-interpolation-mode: nearest-neighbor;
}

// js
var canvas = document.createElement('canvas')
var context = canvas.getContext('2d')

context.webkitImageSmoothingEnabled = false
context.mozImageSmoothingEnabled = false
context.msImageSmoothingEnabled = false
context.imageSmoothingEnabled = false

enter image description here

I'm wondering if there is a way to then figure out where the squares are in the canvas, and what colors they are, so that you can do things with them like (in this case) animate them so it looks like they are sparkling, or perhaps simpler just to animate them back and forth like a wave.

Lance
  • 75,200
  • 93
  • 289
  • 503

1 Answers1

1

I'm afraid it's not possible with the pixelate 'library' due to how it creates the pixelation. It simply stretches a scaled down version of the original image using the original width & height - so there aren't any individual rectangles.

You can do this on your own however. Basically you have do determine a pixelSize for your mosaic - e.g. 16. Now loop over the complete image and get the color of a single 1x1 pixel at screen coordinates that are a multiple of the pixelSize. Finally store every pixel position, it's size and the color in an array.

Now you can loop over the array and draw the individual rectangles to a canvas or animate them as you like.

Here's an example:

Square = function(x, y, w, h, color) {
  this.x = x;
  this.y = y;
  this.width = w;
  this.height = h;
  this.color = color;
}

var squares = new Array();
var canvas = document.createElement("canvas");
var canvas2 = document.createElement("canvas");
canvas.width = canvas2.width = 200;
canvas.height = canvas2.height = 100;
var context = canvas.getContext("2d");
var context2 = canvas2.getContext("2d");
document.body.appendChild(canvas);
document.body.appendChild(canvas2);

function rgbToHex(r, g, b) {
  return ((r << 16) | (g << 8) | b).toString(16);
}

var img = new Image();
img.onload = function() {

  context.drawImage(this, 0, 0);

  var pixelSize = 8;
  var ySteps = Math.round(this.height / pixelSize);
  var xSteps = Math.round(this.width / pixelSize);
  var colorX;
  var colorY;
  var square;
  var color;
  var hexColor;
  
  for (var i = 0; i <= ySteps; i++) {
    if (i == ySteps) {
      colorY = pixelSize * (i - 1);
    } else {
      colorY = pixelSize * (i);
    }

    for (var j = 0; j <= xSteps; j++) {
      if (j == xSteps) {
        colorX = pixelSize * (j - 1);
      } else {
        colorX = pixelSize * (j);
      }

      color = context.getImageData(j * pixelSize, i * pixelSize, 1, 1).data;
      hexColor = "#" + ("000000" + rgbToHex(color[0], color[1], color[2])).slice(-6);

      square = new Square(j * pixelSize, i * pixelSize, pixelSize, pixelSize, hexColor);
      squares.push(square);
    }
  }

  for (var a = 0; a < squares.length; a++) {
    square = squares[a];
    context2.fillStyle = square.color;
    context2.fillRect(square.x, square.y, square.width, square.height);
  }
}

img.crossOrigin = "anonymous";
img.src = "https://picsum.photos/id/76/200/100";
obscure
  • 11,916
  • 2
  • 17
  • 36