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