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