diff options
Diffstat (limited to 'public/assets/js/vendor/renderToCanvas.js')
| -rw-r--r-- | public/assets/js/vendor/renderToCanvas.js | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/public/assets/js/vendor/renderToCanvas.js b/public/assets/js/vendor/renderToCanvas.js new file mode 100644 index 0000000..376e61a --- /dev/null +++ b/public/assets/js/vendor/renderToCanvas.js @@ -0,0 +1,117 @@ +function renderToCanvas(img, options) { + if (!img) return + options = options || {} + + // Canvas max size for any side + var maxSize = 2000 + var canvas = document.createElement('canvas') + var ctx = canvas.getContext('2d') + var initialScale = options.scale || 1 + // Scale to needed to constrain canvas to max size + var scale = getScale(img.width * initialScale, + img.height * initialScale, maxSize, maxSize) + // Still need to apply the user defined scale + scale *= initialScale + var width = canvas.width = Math.round(img.width * scale) + var height = canvas.height = Math.round(img.height * scale) + var correctOrientation = options.correctOrientation + var jpeg = !!img.src.match(/data:image\/jpeg|\.jpeg$|\.jpg$/i) + var dataURI = !!img.src.match(/^data:/) + + ctx.save() + + // Can only correct orientation on JPEGs represented as dataURIs + // for the time being + if (correctOrientation && jpeg && dataURI) { + applyOrientationCorrection() + } + // Resize image if too large + if (scale !== 1) { + ctx.scale(scale, scale) + } + + ctx.drawImage(img, 0, 0) + ctx.restore() + + return canvas + + function applyOrientationCorrection() { + var orientation = getOrientation(img.src) + // Only apply transform if there is some non-normal orientation + if (orientation && orientation !== 1) { + var transform = orientationToTransform[orientation] + var rotation = transform.rotation + var mirror = transform.mirror + var flipAspect = rotation === 90 || rotation === 270 + if (flipAspect) { + // Fancy schmancy swap algo + canvas.width = canvas.height + canvas.width + canvas.height = canvas.width - canvas.height + canvas.width -= canvas.height + } + if (rotation > 0) { + applyRotation(rotation) + } + if (mirror) { + // TODO This is broken. Not sure how to apply this transform + // No biggie, we don't run into this case ATM + // applyMirror() + } + } + } + + /** + * Some images are friggin rotated n shit! (iOS) + * wut the heck + * dang it + * man + * read the EXIF data + * return EXIF orientation value + */ + function getOrientation(uri) { + var exif = new ExifReader + // Split off the base64 data + var base64String = uri.split(',')[1] + // Read off first 128KB, which is all we need to + // get the EXIF data + var arr = base64ToUint8Array(base64String, 0, Math.pow(2, 17)) + try { + exif.load(arr.buffer) + return exif.getTagValue('Orientation') + } catch (err) { + return 1 + } + } + + /** + * Apply rotation such that rotated image will be + * centered in canvas + */ + function applyRotation(deg) { + var radians = deg * (Math.PI / 180) + if (deg === 90) { + ctx.translate(canvas.width, 0) + } else if (deg === 180) { + ctx.translate(canvas.width, canvas.height) + } else if (deg == 270) { + ctx.translate(0, canvas.height) + } + ctx.rotate(radians) + } + + function applyMirror() { + ctx.scale(-1, 1) + } +} + +function base64ToUint8Array(string, start, finish) { + var start = start || 0 + var finish = finish || string.length + // atob that shit + var binary = atob(string) + var buffer = new Uint8Array(binary.length) + for (var i = start; i < finish; i++) { + buffer[i] = binary.charCodeAt(i) + } + return buffer +} |
