Sampling tiles from huge images with html5 canvas
What it does?
- Reads huge e.g. 250Mpixel image from file
- 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
- Uses CSS transformations to show preview how source image is translated.
- 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 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.