1/* 2 * jQuery File Upload Image Preview & Resize Plugin 3 * https://github.com/blueimp/jQuery-File-Upload 4 * 5 * Copyright 2013, Sebastian Tschan 6 * https://blueimp.net 7 * 8 * Licensed under the MIT license: 9 * http://www.opensource.org/licenses/MIT 10 */ 11 12/* jshint nomen:false */ 13/* global define, require, window, Blob */ 14 15(function (factory) { 16 'use strict'; 17 if (typeof define === 'function' && define.amd) { 18 // Register as an anonymous AMD module: 19 define([ 20 'jquery', 21 'load-image', 22 'load-image-meta', 23 'load-image-exif', 24 'canvas-to-blob', 25 './jquery.fileupload-process' 26 ], factory); 27 } else if (typeof exports === 'object') { 28 // Node/CommonJS: 29 factory( 30 require('jquery'), 31 require('blueimp-load-image/js/load-image'), 32 require('blueimp-load-image/js/load-image-meta'), 33 require('blueimp-load-image/js/load-image-exif'), 34 require('blueimp-canvas-to-blob'), 35 require('./jquery.fileupload-process') 36 ); 37 } else { 38 // Browser globals: 39 factory( 40 window.jQuery, 41 window.loadImage 42 ); 43 } 44}(function ($, loadImage) { 45 'use strict'; 46 47 // Prepend to the default processQueue: 48 $.blueimp.fileupload.prototype.options.processQueue.unshift( 49 { 50 action: 'loadImageMetaData', 51 disableImageHead: '@', 52 disableExif: '@', 53 disableExifThumbnail: '@', 54 disableExifSub: '@', 55 disableExifGps: '@', 56 disabled: '@disableImageMetaDataLoad' 57 }, 58 { 59 action: 'loadImage', 60 // Use the action as prefix for the "@" options: 61 prefix: true, 62 fileTypes: '@', 63 maxFileSize: '@', 64 noRevoke: '@', 65 disabled: '@disableImageLoad' 66 }, 67 { 68 action: 'resizeImage', 69 // Use "image" as prefix for the "@" options: 70 prefix: 'image', 71 maxWidth: '@', 72 maxHeight: '@', 73 minWidth: '@', 74 minHeight: '@', 75 crop: '@', 76 orientation: '@', 77 forceResize: '@', 78 disabled: '@disableImageResize' 79 }, 80 { 81 action: 'saveImage', 82 quality: '@imageQuality', 83 type: '@imageType', 84 disabled: '@disableImageResize' 85 }, 86 { 87 action: 'saveImageMetaData', 88 disabled: '@disableImageMetaDataSave' 89 }, 90 { 91 action: 'resizeImage', 92 // Use "preview" as prefix for the "@" options: 93 prefix: 'preview', 94 maxWidth: '@', 95 maxHeight: '@', 96 minWidth: '@', 97 minHeight: '@', 98 crop: '@', 99 orientation: '@', 100 thumbnail: '@', 101 canvas: '@', 102 disabled: '@disableImagePreview' 103 }, 104 { 105 action: 'setImage', 106 name: '@imagePreviewName', 107 disabled: '@disableImagePreview' 108 }, 109 { 110 action: 'deleteImageReferences', 111 disabled: '@disableImageReferencesDeletion' 112 } 113 ); 114 115 // The File Upload Resize plugin extends the fileupload widget 116 // with image resize functionality: 117 $.widget('blueimp.fileupload', $.blueimp.fileupload, { 118 119 options: { 120 // The regular expression for the types of images to load: 121 // matched against the file type: 122 loadImageFileTypes: /^image\/(gif|jpeg|png|svg\+xml)$/, 123 // The maximum file size of images to load: 124 loadImageMaxFileSize: 10000000, // 10MB 125 // The maximum width of resized images: 126 imageMaxWidth: 1920, 127 // The maximum height of resized images: 128 imageMaxHeight: 1080, 129 // Defines the image orientation (1-8) or takes the orientation 130 // value from Exif data if set to true: 131 imageOrientation: false, 132 // Define if resized images should be cropped or only scaled: 133 imageCrop: false, 134 // Disable the resize image functionality by default: 135 disableImageResize: true, 136 // The maximum width of the preview images: 137 previewMaxWidth: 80, 138 // The maximum height of the preview images: 139 previewMaxHeight: 80, 140 // Defines the preview orientation (1-8) or takes the orientation 141 // value from Exif data if set to true: 142 previewOrientation: true, 143 // Create the preview using the Exif data thumbnail: 144 previewThumbnail: true, 145 // Define if preview images should be cropped or only scaled: 146 previewCrop: false, 147 // Define if preview images should be resized as canvas elements: 148 previewCanvas: true 149 }, 150 151 processActions: { 152 153 // Loads the image given via data.files and data.index 154 // as img element, if the browser supports the File API. 155 // Accepts the options fileTypes (regular expression) 156 // and maxFileSize (integer) to limit the files to load: 157 loadImage: function (data, options) { 158 if (options.disabled) { 159 return data; 160 } 161 var that = this, 162 file = data.files[data.index], 163 dfd = $.Deferred(); 164 if (($.type(options.maxFileSize) === 'number' && 165 file.size > options.maxFileSize) || 166 (options.fileTypes && 167 !options.fileTypes.test(file.type)) || 168 !loadImage( 169 file, 170 function (img) { 171 if (img.src) { 172 data.img = img; 173 } 174 dfd.resolveWith(that, [data]); 175 }, 176 options 177 )) { 178 return data; 179 } 180 return dfd.promise(); 181 }, 182 183 // Resizes the image given as data.canvas or data.img 184 // and updates data.canvas or data.img with the resized image. 185 // Also stores the resized image as preview property. 186 // Accepts the options maxWidth, maxHeight, minWidth, 187 // minHeight, canvas and crop: 188 resizeImage: function (data, options) { 189 if (options.disabled || !(data.canvas || data.img)) { 190 return data; 191 } 192 options = $.extend({canvas: true}, options); 193 var that = this, 194 dfd = $.Deferred(), 195 img = (options.canvas && data.canvas) || data.img, 196 resolve = function (newImg) { 197 if (newImg && (newImg.width !== img.width ||
198 newImg.height !== img.height || 199 options.forceResize)) { 200 data[newImg.getContext ? 'canvas' : 'img'] = newImg; 201 } 202 data.preview = newImg; 203 dfd.resolveWith(that, [data]); 204 }, 205 thumbnail; 206 if (data.exif) { 207 if (options.orientation === true) { 208 options.orientation = data.exif.get('Orientation'); 209 } 210 if (options.thumbnail) { 211 thumbnail = data.exif.get('Thumbnail'); 212 if (thumbnail) { 213 loadImage(thumbnail, resolve, options); 214 return dfd.promise(); 215 } 216 } 217 // Prevent orienting the same image twice: 218 if (data.orientation) { 219 delete options.orientation; 220 } else { 221 data.orientation = options.orientation; 222 } 223 } 224 if (img) { 225 resolve(loadImage.scale(img, options)); 226 return dfd.promise(); 227 } 228 return data; 229 }, 230 231 // Saves the processed image given as data.canvas 232 // inplace at data.index of data.files: 233 saveImage: function (data, options) { 234 if (!data.canvas || options.disabled) { 235 return data; 236 } 237 var that = this, 238 file = data.files[data.index], 239 dfd = $.Deferred(); 240 if (data.canvas.toBlob) { 241 data.canvas.toBlob( 242 function (blob) { 243 if (!blob.name) { 244 if (file.type === blob.type) { 245 blob.name = file.name; 246 } else if (file.name) { 247 blob.name = file.name.replace( 248 /\.\w+$/, 249 '.' + blob.type.substr(6) 250 ); 251 } 252 } 253 // Don't restore invalid meta data: 254 if (file.type !== blob.type) { 255 delete data.imageHead; 256 } 257 // Store the created blob at the position 258 // of the original file in the files list: 259 data.files[data.index] = blob; 260 dfd.resolveWith(that, [data]); 261 }, 262 options.type || file.type, 263 options.quality 264 ); 265 } else { 266 return data; 267 } 268 return dfd.promise(); 269 }, 270 271 loadImageMetaData: function (data, options) { 272 if (options.disabled) { 273 return data; 274 } 275 var that = this, 276 dfd = $.Deferred(); 277 loadImage.parseMetaData(data.files[data.index], function (result) { 278 $.extend(data, result); 279 dfd.resolveWith(that, [data]); 280 }, options); 281 return dfd.promise(); 282 }, 283 284 saveImageMetaData: function (data, options) { 285 if (!(data.imageHead && data.canvas && 286 data.canvas.toBlob && !options.disabled)) { 287 return data; 288 } 289 var file = data.files[data.index], 290 blob = new Blob([ 291 data.imageHead, 292 // Resized images always have a head size of 20 bytes, 293 // including the JPEG marker and a minimal JFIF header: 294 this._blobSlice.call(file, 20) 295 ], {type: file.type}); 296 blob.name = file.name; 297 data.files[data.index] = blob; 298 return data; 299 }, 300
301 // Sets the resized version of the image as a property of the 302 // file object, must be called after "saveImage": 303 setImage: function (data, options) { 304 if (data.preview && !options.disabled) { 305 data.files[data.index][options.name || 'preview'] = data.preview; 306 } 307 return data; 308 }, 309 310 deleteImageReferences: function (data, options) { 311 if (!options.disabled) { 312 delete data.img; 313 delete data.canvas; 314 delete data.preview; 315 delete data.imageHead; 316 } 317 return data; 318 } 319 320 } 321 322 }); 323 324}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.