Split image to tiles with HTML5 canvas

Rotate / scale huge images and split it to smaller pieces with html5 canvas. e.g. for creating tiles for custom maps.

Download as .zip Download as .tar.gz View on GitHub

Sampling tiles from huge images with html5 canvas

What it does?

  1. Reads huge e.g. 250Mpixel image from file
  2. Stores original data to full size non visible canvas or to <img> tag that is not attached to DOM and creates visible preview version of image to preview canvas
  3. Uses CSS transformations to show preview how source image is translated.
  4. Apply rotate, scale, and translate to be able to read any part of original image to 256x256 sized tile.

Proof of concept implementation to demonstrate splitting custom map tiles in browser instead of backend. Issues/more info found in https://github.com/elhigu/canvas-image-tiles

Transforming image

Transforming huge image could be slow with canvas, because potentially browser has to transform whole image before starting to drawImage to destination canvas.

So actually we are not doing any transformations to source image, but just do inverse transformations for destination canvas to get correct data from huge source image. I.e. we rotate, scale and move 256x256 square to top of source and then fill it with data from correct position.

Storing full sized source image - canvas or image element?

Full sized source image can be stored in Image() object or in Canvas DOM element.

For some browsers it makes no difference which one is used, but for other browsers, e.g. desktop Chrome storing data in Image() object causes performance loss and jumpy memory consumption when drawing data to destination canvas.

On some platforms (e.g. iOS Chrome and Safari) Image() object uses a lot less memory and just works better.

Currently by default slicer stores original data in off screen canvas, except for iOS where using Image() object seems to work better.

Preview image for adjusting rotation and scale

Showing the full size image in <img> tag and scaling it with CSS is slow for big images.

For adjusting image orientation we create smaller canvas of 2048px width or height (keeping correct aspect ratio) and draw downscaled version of the original image.

On UI side we can show preview canvas with correct orientation by applying direct CSS transformations to preview (so that in preview it looks like the source image is transformed). However when data is copied from full sized source we apply inverse transformation for destination canvas for doing actual copying image data from full size source to destination canvas.

Helper class does automatically all the direct / inverse transformation calculations and outputs directly correct CSS line for direct transformations and internally applies inverse transformations when creating tile from source image.

Try it

Reads file in, creates / shows preview (max 2048x2048). Preview canvas is used to position image on top of area where one can select which part of image should be read to 256x256 tile.

iOS does automatic downscaling when loading big images, so don't be amazed if image dimensions seem different than you would expect. Also on iOS really big images (like 200Mpix) just silently fail.

Drag from S (Scale) and R (Rotate) buttons to adjust preview image position. Or use pinch, rotate, tap, pan touch gestures on touch devices.

Choose image:
Fps:
Image size:
Click area below to select tile position
R
S