How to split up an image in pieces and reshuffle it, using HTML, Javascript or CamanJS?

JohnAndrews picture JohnAndrews · Nov 21, 2014 · Viewed 6.9k times · Source

I want to create puzzle images out of original images, meaning that an image is cut into 9 pieces (3x3) and then shuffled and stored as a new image. Does anyone know which method is the best to do so and how to achieve it? Perhaps with CamanJS? Does anyone have an example code?

Answer

markE picture markE · Nov 21, 2014

enter image description hereenter image description here

Canvas can do this using the clipping version of context.drawImage.

context.drawImage allows you to clip your 9 sub-pieces from the original image and then draw them anywhere on the canvas.

The clipping version of drawImage takes these arguments:

  • the image to be clipped: img

  • the [clipLeft, clipTop] in the original image where clipping starts

  • the [clipWidth, clipHeight] size of the sub-image to be clipped from the original image

  • the [drawLeft, drawTop] on the Canvas where the clipped sub-image will start drawing

  • the [drawWidth, drawHeight] is scaled size of the sub-image to be drawn on the canvas

    • If drawWidth==clipWidth and drawHeight==clipHeight, the sub-image will be drawn at the same size clipped from the original.

    • If drawWidth!==clipWidth and drawHeight!==clipHeight, the sub-image will be scaled and then drawn.

Here's example code and a Demo that randomly draws the clipped pieces onto the canvas. It shuffles an array to define random positions for the pieces and then draws those pieces using drawImage.

var canvas=document.getElementById("canvas");
var ctx=canvas.getContext("2d");
var cw=canvas.width;
var ch=canvas.height;

var rows=3;
var cols=3;

var img=new Image();
img.onload=start;
img.src="https://dl.dropboxusercontent.com/u/139992952/multple/sailboat.png";
function start(){

  var iw=canvas.width=img.width;
  var ih=canvas.height=img.height;
  var pieceWidth=iw/cols;
  var pieceHeight=ih/rows;

  var pieces = [
    {col:0,row:0},
    {col:1,row:0},
    {col:2,row:0},
    {col:0,row:1},
    {col:1,row:1},
    {col:2,row:1},
    {col:0,row:2},
    {col:1,row:2},
    {col:2,row:2},
  ]
    shuffle(pieces);

    var i=0;
    for(var y=0;y<rows;y++){
    for(var x=0;x<cols;x++){
    var p=pieces[i++];
  ctx.drawImage(
    // from the original image
    img,
    // take the next x,y piece
    x*pieceWidth, y*pieceHeight, pieceWidth, pieceHeight,
    // draw it on canvas based on the shuffled pieces[] array
    p.col*pieceWidth, p.row*pieceHeight, pieceWidth, pieceHeight
  );
}}


}

function shuffle(a){
  for(var j, x, i = a.length; i; j = Math.floor(Math.random() * i), x = a[--i], a[i] = a[j], a[j] = x);
  return a;
};
body{ background-color: ivory; padding:10px; }
#canvas{border:1px solid red;}
<canvas id="canvas" width=300 height=300></canvas>