UNPKG

@r3l/app

Version:
286 lines (232 loc) 6.99 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); Object.defineProperty(exports, "__esModule", { value: true }); exports.resizeImage = resizeImage; exports.loadFile = loadFile; exports.renderToCanvas = renderToCanvas; exports.downsample = downsample; exports.loadImage = loadImage; exports.MAX_FILE_SIZE = exports.MAX_IMAGE_DIMENSION = void 0; var _exifreader = _interopRequireDefault(require("exifreader")); var _dataUriToBuffer = _interopRequireDefault(require("data-uri-to-buffer")); var _base = require("base-64"); if (!global.btoa) global.btoa = _base.encode; if (!global.atob) global.atob = _base.decode; /* Image resize / EXIF processing functions */ var MAX_IMAGE_DIMENSION = 1024; exports.MAX_IMAGE_DIMENSION = MAX_IMAGE_DIMENSION; var MAX_FILE_SIZE = 1024 * 400; exports.MAX_FILE_SIZE = MAX_FILE_SIZE; var RESIZE = 'https://dqclwwljzk4fq.cloudfront.net/'; var S3URL = /https:\/\/relevant-image.s3.amazonaws.com\/|https:\/\/s3.amazonaws.com\/relevant-image\//; function checkImageURL(url) { return url.match(/\.(jpeg|jpg|png|webp|tiff)$/) != null; } function resizeImage(url, w, h) { if (!url) return null; if (!url.match(S3URL) || !checkImageURL(url)) return url; return url.replace(S3URL, "".concat(RESIZE, "fit-in/").concat(w * 8 * 3, "x").concat(h * 8 * 3, "/")); } function loadFile(file) { return new Promise(function (resolve) { var reader = new FileReader(); reader.onload = function (e) { return resolve(e.target.result); }; reader.readAsArrayBuffer(file); }); } function getScale(width, height, viewportWidth, viewportHeight, fillViewport) { function fitHorizontal() { return viewportWidth / width; } function fitVertical() { return viewportHeight / height; } fillViewport = !!fillViewport; var landscape = width / height > viewportWidth / viewportHeight; if (landscape) { if (fillViewport) { return fitVertical(); } if (width > viewportWidth) { return fitHorizontal(); } } else { if (fillViewport) { return fitHorizontal(); } if (height > viewportHeight) { return fitVertical(); } } return 1; } function applyRotation(canvas, ctx, 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 base64ToUint8Array(string, start, finish) { start = start || 0; finish = finish || string.length; var binary = atob(string); var buffer = new Uint8Array(binary.length); for (var i = start; i < finish; i++) { buffer[i] = binary.charCodeAt(i); } return buffer; } function getOrientation(uri) { // Split off the base64 URL header 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 { var tags = _exifreader.default.load(arr.buffer); return tags.Orientation.value; } catch (err) { return 1; } } /** * Mapping from EXIF orientation values to data * regarding the rotation and mirroring necessary to * render the canvas correctly * Derived from: * http://www.daveperrett.com/articles/2012/07/28/exif-orientation-handling-is-a-ghetto/ */ var orientationToTransform = { 1: { rotation: 0, mirror: false }, 2: { rotation: 0, mirror: true }, 3: { rotation: 180, mirror: false }, 4: { rotation: 180, mirror: true }, 5: { rotation: 90, mirror: true }, 6: { rotation: 90, mirror: false }, 7: { rotation: 270, mirror: true }, 8: { rotation: 270, mirror: false } }; function applyOrientationCorrection(canvas, ctx, uri) { var orientation = getOrientation(uri); // Only apply transform if there is some non-normal orientation if (orientation && orientation !== 1) { var rotation = orientationToTransform[orientation].rotation; 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(canvas, ctx, rotation); } } } function renderToCanvas(img, options) { if (!img) return null; options = options || {}; // Canvas max size for any side 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, MAX_IMAGE_DIMENSION, MAX_IMAGE_DIMENSION, true); // Still need to apply the user defined scale scale *= initialScale; canvas.width = Math.round(img.width * scale); canvas.height = Math.round(img.height * scale); var _options = options, correctOrientation = _options.correctOrientation; var jpeg = !!img.src.match(/data:image\/jpeg|\.jpeg$|\.jpg$/i); var hasDataURI = !!img.src.match(/^data:/); ctx.save(); // Can only correct orientation on JPEGs represented as dataURIs // for the time being if (correctOrientation && jpeg && hasDataURI) { applyOrientationCorrection(canvas, ctx, img.src); } // Resize image if too large if (scale !== 1) { ctx.scale(scale, scale); } ctx.drawImage(img, 0, 0); ctx.restore(); return canvas; } function downsample(img) { var resized = renderToCanvas(img, { correctOrientation: true }); var buf; var dataURL; var quality = 0.8; do { dataURL = resized.toDataURL('image/jpeg', quality); buf = (0, _dataUriToBuffer.default)(dataURL); quality -= 0.05; } while (buf.length > MAX_FILE_SIZE && quality > 0.1); return dataURL; } function loadImage(file) { return new Promise(function (resolve, reject) { if (file) { var reader = new FileReader(); reader.onload = function (e) { reader.onload = null; reader.onerror = null; var dataURL = e.target.result; var buf = (0, _dataUriToBuffer.default)(dataURL); if (buf.length <= MAX_FILE_SIZE) { resolve(dataURL); } else { var img = new Image(); img.onload = function () { img.onload = null; img.onerror = null; resolve(downsample(img)); }; img.onerror = function () { img.onload = null; img.onerror = null; reject(); }; img.src = dataURL; } }; reader.onerror = function () { reader.onload = null; reader.onerror = null; reject(); }; reader.readAsDataURL(file); } else reject(); }); } //# sourceMappingURL=img.js.map