When dealing with a large number of images, sometimes it’s easier to group all of them in a single file rather than making a file for each image. This may make it easier to track related images, say, a group of sprites for a video game character. It can also make for more efficient compression, since you don’t need to store as much overhead as you would for a bunch of individual image files. Coincidentally, it also makes it easier to download test images for programs listed in blog posts.
The program shown loads a single image file (provided below as “RedGreenBlueYellow.png”) and breaks it into a bunch of equally sized tiles.
Note that certain browsers may have security features that throw errors if the HTML5 Canvas object’s toDataURL() function is called under certain circumstances. For example, to run the program in Google’s Chrome browser, it is necessary to run “chrome.exe” with the “–allow-file-access-from-files” switch.
var program = new ImageSlicingTest();
program.main();
function ImageSlicingTest()
{
this.main = function()
{
var imageToSlice = new Image();
imageToSlice.onload = main2;
imageToSlice.src = "RedGreenBlueYellow.png";
}
function main2(event)
{
var imageToSlice = event.target;
var imageTiles = new ImageHelper().sliceImageIntoTiles
(
imageToSlice,
new Coords(4, 1)
);
var imageTileSize = new Coords(imageTiles[0].width, imageTiles[0].height);
for (var i = 0; i < imageTiles.length; i++)
{
var imageTile = imageTiles[i];
var drawPos = new Coords(i * 2, 0).multiply(imageTileSize);
imageTile.style.left = drawPos.x;
imageTile.style.top = drawPos.y;
document.body.appendChild(imageTile);
}
}
}
function Coords(x, y)
{
this.x = x;
this.y = y;
this.clone = function()
{
return new Coords(this.x, this.y);
}
this.divide = function(other)
{
this.x /= other.x;
this.y /= other.y;
return this;
}
this.multiply = function(other)
{
this.x *= other.x;
this.y *= other.y;
return this;
}
this.overwriteWith = function(other)
{
this.x = other.x;
this.y = other.y;
return this;
}
this.toString = function()
{
return "(" + this.x + "," + this.y + ")";
}
}
function ImageHelper()
{
this.sliceImageIntoTiles = function(imageToSlice, sizeInTiles)
{
var returnImages = new Array();
var imageToSliceSize = new Coords(imageToSlice.width, imageToSlice.height);
var tileSize = imageToSliceSize.clone().divide(sizeInTiles);
var tilePos = new Coords(0, 0);
var sourcePos = new Coords(0, 0);
for (var y = 0; y < sizeInTiles.y; y++)
{
tilePos.y = y;
for (var x = 0; x < sizeInTiles.x; x++)
{
tilePos.x = x;
var canvas = document.createElement("canvas");
canvas.id = "tile_" + x + "_" + y;
canvas.width = tileSize.x;
canvas.height = tileSize.y;
canvas.style.position = "absolute";
var graphics = canvas.getContext("2d");
sourcePos.overwriteWith(tilePos).multiply(tileSize);
graphics.drawImage
(
imageToSlice,
sourcePos.x, sourcePos.y, // source pos
tileSize.x, tileSize.y, // source size
0, 0, // destination pos
tileSize.x, tileSize.y // destination size
);
// browser dependent?
var imageFromCanvasURL = canvas.toDataURL("image/png");
var imageFromCanvas = document.createElement("img");
imageFromCanvas.width = canvas.width;
imageFromCanvas.height = canvas.height;
imageFromCanvas.style.position = "absolute";
imageFromCanvas.src = imageFromCanvasURL;
returnImages.push(imageFromCanvas);
}
}
return returnImages;
}
}
