1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 |
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 |
|
36 |
|
37 |
|
38 |
|
39 |
|
40 |
|
41 |
|
42 |
|
43 | ;(function (factory) {
|
44 | 'use strict'
|
45 | if (typeof define === 'function' && define.amd) {
|
46 |
|
47 | define(['./load-image', './load-image-scale', './load-image-meta'], factory)
|
48 | } else if (typeof module === 'object' && module.exports) {
|
49 | factory(
|
50 | require('./load-image'),
|
51 | require('./load-image-scale'),
|
52 | require('./load-image-meta')
|
53 | )
|
54 | } else {
|
55 |
|
56 | factory(window.loadImage)
|
57 | }
|
58 | })(function (loadImage) {
|
59 | 'use strict'
|
60 |
|
61 | var originalTransform = loadImage.transform
|
62 | var originalRequiresCanvas = loadImage.requiresCanvas
|
63 | var originalRequiresMetaData = loadImage.requiresMetaData
|
64 | var originalTransformCoordinates = loadImage.transformCoordinates
|
65 | var originalGetTransformedOptions = loadImage.getTransformedOptions
|
66 |
|
67 | ;(function ($) {
|
68 |
|
69 | if (!$.global.document) return
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | var testImageURL =
|
76 | 'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' +
|
77 | 'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' +
|
78 | 'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' +
|
79 | 'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAIAAwMBEQACEQEDEQH/x' +
|
80 | 'ABRAAEAAAAAAAAAAAAAAAAAAAAKEAEBAQADAQEAAAAAAAAAAAAGBQQDCAkCBwEBAAAAAAA' +
|
81 | 'AAAAAAAAAAAAAABEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AG8T9NfSMEVMhQ' +
|
82 | 'voP3fFiRZ+MTHDifa/95OFSZU5OzRzxkyejv8ciEfhSceSXGjS8eSdLnZc2HDm4M3BxcXw' +
|
83 | 'H/9k='
|
84 | var img = document.createElement('img')
|
85 | img.onload = function () {
|
86 |
|
87 | $.orientation = img.width === 2 && img.height === 3
|
88 | if ($.orientation) {
|
89 | var canvas = $.createCanvas(1, 1, true)
|
90 | var ctx = canvas.getContext('2d')
|
91 | ctx.drawImage(img, 1, 1, 1, 1, 0, 0, 1, 1)
|
92 |
|
93 |
|
94 |
|
95 |
|
96 |
|
97 |
|
98 |
|
99 | $.orientationCropBug =
|
100 | ctx.getImageData(0, 0, 1, 1).data.toString() !== '255,255,255,255'
|
101 | }
|
102 | }
|
103 | img.src = testImageURL
|
104 | })(loadImage)
|
105 |
|
106 | |
107 |
|
108 |
|
109 |
|
110 |
|
111 |
|
112 |
|
113 | function requiresCanvasOrientation(options, withMetaData) {
|
114 | var orientation = options && options.orientation
|
115 | return (
|
116 |
|
117 | (orientation === true && !loadImage.orientation) ||
|
118 |
|
119 | (orientation === 1 && loadImage.orientation) ||
|
120 |
|
121 | ((!withMetaData || loadImage.orientation) &&
|
122 | orientation > 1 &&
|
123 | orientation < 9)
|
124 | )
|
125 | }
|
126 |
|
127 | |
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 | function requiresOrientationChange(orientation, autoOrientation) {
|
135 | return (
|
136 | orientation !== autoOrientation &&
|
137 | ((orientation === 1 && autoOrientation > 1 && autoOrientation < 9) ||
|
138 | (orientation > 1 && orientation < 9))
|
139 | )
|
140 | }
|
141 |
|
142 | |
143 |
|
144 |
|
145 |
|
146 |
|
147 |
|
148 |
|
149 |
|
150 |
|
151 |
|
152 |
|
153 |
|
154 |
|
155 |
|
156 |
|
157 |
|
158 |
|
159 |
|
160 | function requiresRot180(orientation, autoOrientation) {
|
161 | if (autoOrientation > 1 && autoOrientation < 9) {
|
162 | switch (orientation) {
|
163 | case 2:
|
164 | case 4:
|
165 | return autoOrientation > 4
|
166 | case 5:
|
167 | case 7:
|
168 | return autoOrientation % 2 === 0
|
169 | case 6:
|
170 | case 8:
|
171 | return (
|
172 | autoOrientation === 2 ||
|
173 | autoOrientation === 4 ||
|
174 | autoOrientation === 5 ||
|
175 | autoOrientation === 7
|
176 | )
|
177 | }
|
178 | }
|
179 | return false
|
180 | }
|
181 |
|
182 |
|
183 | loadImage.requiresCanvas = function (options) {
|
184 | return (
|
185 | requiresCanvasOrientation(options) ||
|
186 | originalRequiresCanvas.call(loadImage, options)
|
187 | )
|
188 | }
|
189 |
|
190 |
|
191 | loadImage.requiresMetaData = function (options) {
|
192 | return (
|
193 | requiresCanvasOrientation(options, true) ||
|
194 | originalRequiresMetaData.call(loadImage, options)
|
195 | )
|
196 | }
|
197 |
|
198 | loadImage.transform = function (img, options, callback, file, data) {
|
199 | originalTransform.call(
|
200 | loadImage,
|
201 | img,
|
202 | options,
|
203 | function (img, data) {
|
204 | if (data) {
|
205 | var autoOrientation =
|
206 | loadImage.orientation && data.exif && data.exif.get('Orientation')
|
207 | if (autoOrientation > 4 && autoOrientation < 9) {
|
208 |
|
209 | var originalWidth = data.originalWidth
|
210 | var originalHeight = data.originalHeight
|
211 | data.originalWidth = originalHeight
|
212 | data.originalHeight = originalWidth
|
213 | }
|
214 | }
|
215 | callback(img, data)
|
216 | },
|
217 | file,
|
218 | data
|
219 | )
|
220 | }
|
221 |
|
222 |
|
223 |
|
224 | loadImage.getTransformedOptions = function (img, opts, data) {
|
225 | var options = originalGetTransformedOptions.call(loadImage, img, opts)
|
226 | var exifOrientation = data.exif && data.exif.get('Orientation')
|
227 | var orientation = options.orientation
|
228 | var autoOrientation = loadImage.orientation && exifOrientation
|
229 | if (orientation === true) orientation = exifOrientation
|
230 | if (!requiresOrientationChange(orientation, autoOrientation)) {
|
231 | return options
|
232 | }
|
233 | var top = options.top
|
234 | var right = options.right
|
235 | var bottom = options.bottom
|
236 | var left = options.left
|
237 | var newOptions = {}
|
238 | for (var i in options) {
|
239 | if (Object.prototype.hasOwnProperty.call(options, i)) {
|
240 | newOptions[i] = options[i]
|
241 | }
|
242 | }
|
243 | newOptions.orientation = orientation
|
244 | if (
|
245 | (orientation > 4 && !(autoOrientation > 4)) ||
|
246 | (orientation < 5 && autoOrientation > 4)
|
247 | ) {
|
248 |
|
249 | newOptions.maxWidth = options.maxHeight
|
250 | newOptions.maxHeight = options.maxWidth
|
251 | newOptions.minWidth = options.minHeight
|
252 | newOptions.minHeight = options.minWidth
|
253 | newOptions.sourceWidth = options.sourceHeight
|
254 | newOptions.sourceHeight = options.sourceWidth
|
255 | }
|
256 | if (autoOrientation > 1) {
|
257 |
|
258 |
|
259 | switch (autoOrientation) {
|
260 | case 2:
|
261 |
|
262 | right = options.left
|
263 | left = options.right
|
264 | break
|
265 | case 3:
|
266 |
|
267 | top = options.bottom
|
268 | right = options.left
|
269 | bottom = options.top
|
270 | left = options.right
|
271 | break
|
272 | case 4:
|
273 |
|
274 | top = options.bottom
|
275 | bottom = options.top
|
276 | break
|
277 | case 5:
|
278 |
|
279 | top = options.left
|
280 | right = options.bottom
|
281 | bottom = options.right
|
282 | left = options.top
|
283 | break
|
284 | case 6:
|
285 |
|
286 | top = options.left
|
287 | right = options.top
|
288 | bottom = options.right
|
289 | left = options.bottom
|
290 | break
|
291 | case 7:
|
292 |
|
293 | top = options.right
|
294 | right = options.top
|
295 | bottom = options.left
|
296 | left = options.bottom
|
297 | break
|
298 | case 8:
|
299 |
|
300 | top = options.right
|
301 | right = options.bottom
|
302 | bottom = options.left
|
303 | left = options.top
|
304 | break
|
305 | }
|
306 |
|
307 | if (requiresRot180(orientation, autoOrientation)) {
|
308 | var tmpTop = top
|
309 | var tmpRight = right
|
310 | top = bottom
|
311 | right = left
|
312 | bottom = tmpTop
|
313 | left = tmpRight
|
314 | }
|
315 | }
|
316 | newOptions.top = top
|
317 | newOptions.right = right
|
318 | newOptions.bottom = bottom
|
319 | newOptions.left = left
|
320 |
|
321 | switch (orientation) {
|
322 | case 2:
|
323 |
|
324 | newOptions.right = left
|
325 | newOptions.left = right
|
326 | break
|
327 | case 3:
|
328 |
|
329 | newOptions.top = bottom
|
330 | newOptions.right = left
|
331 | newOptions.bottom = top
|
332 | newOptions.left = right
|
333 | break
|
334 | case 4:
|
335 |
|
336 | newOptions.top = bottom
|
337 | newOptions.bottom = top
|
338 | break
|
339 | case 5:
|
340 |
|
341 | newOptions.top = left
|
342 | newOptions.right = bottom
|
343 | newOptions.bottom = right
|
344 | newOptions.left = top
|
345 | break
|
346 | case 6:
|
347 |
|
348 | newOptions.top = right
|
349 | newOptions.right = bottom
|
350 | newOptions.bottom = left
|
351 | newOptions.left = top
|
352 | break
|
353 | case 7:
|
354 |
|
355 | newOptions.top = right
|
356 | newOptions.right = top
|
357 | newOptions.bottom = left
|
358 | newOptions.left = bottom
|
359 | break
|
360 | case 8:
|
361 |
|
362 | newOptions.top = left
|
363 | newOptions.right = top
|
364 | newOptions.bottom = right
|
365 | newOptions.left = bottom
|
366 | break
|
367 | }
|
368 | return newOptions
|
369 | }
|
370 |
|
371 |
|
372 | loadImage.transformCoordinates = function (canvas, options, data) {
|
373 | originalTransformCoordinates.call(loadImage, canvas, options, data)
|
374 | var orientation = options.orientation
|
375 | var autoOrientation =
|
376 | loadImage.orientation && data.exif && data.exif.get('Orientation')
|
377 | if (!requiresOrientationChange(orientation, autoOrientation)) {
|
378 | return
|
379 | }
|
380 | var ctx = canvas.getContext('2d')
|
381 | var width = canvas.width
|
382 | var height = canvas.height
|
383 | var sourceWidth = width
|
384 | var sourceHeight = height
|
385 | if (
|
386 | (orientation > 4 && !(autoOrientation > 4)) ||
|
387 | (orientation < 5 && autoOrientation > 4)
|
388 | ) {
|
389 |
|
390 | canvas.width = height
|
391 | canvas.height = width
|
392 | }
|
393 | if (orientation > 4) {
|
394 |
|
395 | sourceWidth = height
|
396 | sourceHeight = width
|
397 | }
|
398 |
|
399 | switch (autoOrientation) {
|
400 | case 2:
|
401 |
|
402 | ctx.translate(sourceWidth, 0)
|
403 | ctx.scale(-1, 1)
|
404 | break
|
405 | case 3:
|
406 |
|
407 | ctx.translate(sourceWidth, sourceHeight)
|
408 | ctx.rotate(Math.PI)
|
409 | break
|
410 | case 4:
|
411 |
|
412 | ctx.translate(0, sourceHeight)
|
413 | ctx.scale(1, -1)
|
414 | break
|
415 | case 5:
|
416 |
|
417 | ctx.rotate(-0.5 * Math.PI)
|
418 | ctx.scale(-1, 1)
|
419 | break
|
420 | case 6:
|
421 |
|
422 | ctx.rotate(-0.5 * Math.PI)
|
423 | ctx.translate(-sourceWidth, 0)
|
424 | break
|
425 | case 7:
|
426 |
|
427 | ctx.rotate(-0.5 * Math.PI)
|
428 | ctx.translate(-sourceWidth, sourceHeight)
|
429 | ctx.scale(1, -1)
|
430 | break
|
431 | case 8:
|
432 |
|
433 | ctx.rotate(0.5 * Math.PI)
|
434 | ctx.translate(0, -sourceHeight)
|
435 | break
|
436 | }
|
437 |
|
438 | if (requiresRot180(orientation, autoOrientation)) {
|
439 | ctx.translate(sourceWidth, sourceHeight)
|
440 | ctx.rotate(Math.PI)
|
441 | }
|
442 | switch (orientation) {
|
443 | case 2:
|
444 |
|
445 | ctx.translate(width, 0)
|
446 | ctx.scale(-1, 1)
|
447 | break
|
448 | case 3:
|
449 |
|
450 | ctx.translate(width, height)
|
451 | ctx.rotate(Math.PI)
|
452 | break
|
453 | case 4:
|
454 |
|
455 | ctx.translate(0, height)
|
456 | ctx.scale(1, -1)
|
457 | break
|
458 | case 5:
|
459 |
|
460 | ctx.rotate(0.5 * Math.PI)
|
461 | ctx.scale(1, -1)
|
462 | break
|
463 | case 6:
|
464 |
|
465 | ctx.rotate(0.5 * Math.PI)
|
466 | ctx.translate(0, -height)
|
467 | break
|
468 | case 7:
|
469 |
|
470 | ctx.rotate(0.5 * Math.PI)
|
471 | ctx.translate(width, -height)
|
472 | ctx.scale(-1, 1)
|
473 | break
|
474 | case 8:
|
475 |
|
476 | ctx.rotate(-0.5 * Math.PI)
|
477 | ctx.translate(-width, 0)
|
478 | break
|
479 | }
|
480 | }
|
481 | })
|