UNPKG

blueimp-load-image

Version:

JavaScript Load Image is a library to load images provided as File or Blob objects or via URL. It returns an optionally scaled, cropped or rotated HTML img or canvas element. It also provides methods to parse image metadata to extract IPTC and Exif tags a

230 lines (214 loc) 6.7 kB
/* * JavaScript Load Image * https://github.com/blueimp/JavaScript-Load-Image * * Copyright 2011, Sebastian Tschan * https://blueimp.net * * Licensed under the MIT license: * https://opensource.org/licenses/MIT */ /* global define, module, Promise */ ;(function ($) { 'use strict' var urlAPI = $.URL || $.webkitURL /** * Creates an object URL for a given File object. * * @param {Blob} blob Blob object * @returns {string|boolean} Returns object URL if API exists, else false. */ function createObjectURL(blob) { return urlAPI ? urlAPI.createObjectURL(blob) : false } /** * Revokes a given object URL. * * @param {string} url Blob object URL * @returns {undefined|boolean} Returns undefined if API exists, else false. */ function revokeObjectURL(url) { return urlAPI ? urlAPI.revokeObjectURL(url) : false } /** * Helper function to revoke an object URL * * @param {string} url Blob Object URL * @param {object} [options] Options object */ function revokeHelper(url, options) { if (url && url.slice(0, 5) === 'blob:' && !(options && options.noRevoke)) { revokeObjectURL(url) } } /** * Loads a given File object via FileReader interface. * * @param {Blob} file Blob object * @param {Function} onload Load event callback * @param {Function} [onerror] Error/Abort event callback * @param {string} [method=readAsDataURL] FileReader method * @returns {FileReader|boolean} Returns FileReader if API exists, else false. */ function readFile(file, onload, onerror, method) { if (!$.FileReader) return false var reader = new FileReader() reader.onload = function () { onload.call(reader, this.result) } if (onerror) { reader.onabort = reader.onerror = function () { onerror.call(reader, this.error) } } var readerMethod = reader[method || 'readAsDataURL'] if (readerMethod) { readerMethod.call(reader, file) return reader } } /** * Cross-frame instanceof check. * * @param {string} type Instance type * @param {object} obj Object instance * @returns {boolean} Returns true if the object is of the given instance. */ function isInstanceOf(type, obj) { // Cross-frame instanceof check return Object.prototype.toString.call(obj) === '[object ' + type + ']' } /** * @typedef { HTMLImageElement|HTMLCanvasElement } Result */ /** * Loads an image for a given File object. * * @param {Blob|string} file Blob object or image URL * @param {Function|object} [callback] Image load event callback or options * @param {object} [options] Options object * @returns {HTMLImageElement|FileReader|Promise<Result>} Object */ function loadImage(file, callback, options) { /** * Promise executor * * @param {Function} resolve Resolution function * @param {Function} reject Rejection function * @returns {HTMLImageElement|FileReader} Object */ function executor(resolve, reject) { var img = document.createElement('img') var url /** * Callback for the fetchBlob call. * * @param {HTMLImageElement|HTMLCanvasElement} img Error object * @param {object} data Data object * @returns {undefined} Undefined */ function resolveWrapper(img, data) { if (resolve === reject) { // Not using Promises if (resolve) resolve(img, data) return } else if (img instanceof Error) { reject(img) return } data = data || {} // eslint-disable-line no-param-reassign data.image = img resolve(data) } /** * Callback for the fetchBlob call. * * @param {Blob} blob Blob object * @param {Error} err Error object */ function fetchBlobCallback(blob, err) { if (err && $.console) console.log(err) // eslint-disable-line no-console if (blob && isInstanceOf('Blob', blob)) { file = blob // eslint-disable-line no-param-reassign url = createObjectURL(file) } else { url = file if (options && options.crossOrigin) { img.crossOrigin = options.crossOrigin } } img.src = url } img.onerror = function (event) { revokeHelper(url, options) if (reject) reject.call(img, event) } img.onload = function () { revokeHelper(url, options) var data = { originalWidth: img.naturalWidth || img.width, originalHeight: img.naturalHeight || img.height } try { loadImage.transform(img, options, resolveWrapper, file, data) } catch (error) { if (reject) reject(error) } } if (typeof file === 'string') { if (loadImage.requiresMetaData(options)) { loadImage.fetchBlob(file, fetchBlobCallback, options) } else { fetchBlobCallback() } return img } else if (isInstanceOf('Blob', file) || isInstanceOf('File', file)) { url = createObjectURL(file) if (url) { img.src = url return img } return readFile( file, function (url) { img.src = url }, reject ) } } if ($.Promise && typeof callback !== 'function') { options = callback // eslint-disable-line no-param-reassign return new Promise(executor) } return executor(callback, callback) } // Determines if metadata should be loaded automatically. // Requires the load image meta extension to load metadata. loadImage.requiresMetaData = function (options) { return options && options.meta } // If the callback given to this function returns a blob, it is used as image // source instead of the original url and overrides the file argument used in // the onload and onerror event callbacks: loadImage.fetchBlob = function (url, callback) { callback() } loadImage.transform = function (img, options, callback, file, data) { callback(img, data) } loadImage.global = $ loadImage.readFile = readFile loadImage.isInstanceOf = isInstanceOf loadImage.createObjectURL = createObjectURL loadImage.revokeObjectURL = revokeObjectURL if (typeof define === 'function' && define.amd) { define(function () { return loadImage }) } else if (typeof module === 'object' && module.exports) { module.exports = loadImage } else { $.loadImage = loadImage } })((typeof window !== 'undefined' && window) || this)