Skip to content

Commit e9a1a96

Browse files
committed
Update JavaScript Load Image to 1.9.0
1 parent ec3e9a3 commit e9a1a96

File tree

1 file changed

+183
-135
lines changed

1 file changed

+183
-135
lines changed

vendor/assets/javascripts/jquery-fileupload/vendor/load-image.js

Lines changed: 183 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,16 @@
11
/*
2-
* JavaScript Load Image 1.3.1
2+
* JavaScript Load Image 1.9.0
33
* https://github.com/blueimp/JavaScript-Load-Image
44
*
55
* Copyright 2011, Sebastian Tschan
66
* https://blueimp.net
77
*
8-
* iOS image scaling fixes based on
9-
* https://github.com/stomita/ios-imagefile-megapixel
10-
*
118
* Licensed under the MIT license:
129
* http://www.opensource.org/licenses/MIT
1310
*/
1411

15-
/*jslint nomen: true, bitwise: true */
16-
/*global window, document, URL, webkitURL, Blob, File, FileReader, define */
12+
/*jslint nomen: true */
13+
/*global define, window, document, URL, webkitURL, Blob, File, FileReader */
1714

1815
(function ($) {
1916
'use strict';
@@ -30,17 +27,24 @@
3027
if (oUrl && !(options && options.noRevoke)) {
3128
loadImage.revokeObjectURL(oUrl);
3229
}
33-
callback(loadImage.scale(img, options));
30+
if (callback) {
31+
callback(loadImage.scale(img, options));
32+
}
3433
};
35-
if ((window.Blob && file instanceof Blob) ||
36-
// Files are also Blob instances, but some browsers
37-
// (Firefox 3.6) support the File API but not Blobs:
38-
(window.File && file instanceof File)) {
34+
if (loadImage.isInstanceOf('Blob', file) ||
35+
// Files are also Blob instances, but some browsers
36+
// (Firefox 3.6) support the File API but not Blobs:
37+
loadImage.isInstanceOf('File', file)) {
3938
url = oUrl = loadImage.createObjectURL(file);
4039
// Store the file type for resize processing:
4140
img._type = file.type;
42-
} else {
41+
} else if (typeof file === 'string') {
4342
url = file;
43+
if (options && options.crossOrigin) {
44+
img.crossOrigin = options.crossOrigin;
45+
}
46+
} else {
47+
return false;
4448
}
4549
if (url) {
4650
img.src = url;
@@ -51,7 +55,9 @@
5155
if (target && target.result) {
5256
img.src = target.result;
5357
} else {
54-
callback(e);
58+
if (callback) {
59+
callback(e);
60+
}
5561
}
5662
});
5763
},
@@ -61,139 +67,178 @@
6167
(window.URL && URL.revokeObjectURL && URL) ||
6268
(window.webkitURL && webkitURL);
6369

64-
// Detects subsampling in JPEG images:
65-
loadImage.detectSubsampling = function (img) {
66-
var iw = img.width,
67-
ih = img.height,
68-
canvas,
69-
ctx;
70-
if (iw * ih > 1024 * 1024) { // only consider mexapixel images
71-
canvas = document.createElement('canvas');
72-
canvas.width = canvas.height = 1;
73-
ctx = canvas.getContext('2d');
74-
ctx.drawImage(img, -iw + 1, 0);
75-
// subsampled image becomes half smaller in rendering size.
76-
// check alpha channel value to confirm image is covering edge pixel or not.
77-
// if alpha value is 0 image is not covering, hence subsampled.
78-
return ctx.getImageData(0, 0, 1, 1).data[3] === 0;
79-
}
80-
return false;
70+
loadImage.isInstanceOf = function (type, obj) {
71+
// Cross-frame instanceof check
72+
return Object.prototype.toString.call(obj) === '[object ' + type + ']';
8173
};
8274

83-
// Detects vertical squash in JPEG images:
84-
loadImage.detectVerticalSquash = function (img, ih) {
85-
var canvas = document.createElement('canvas'),
86-
ctx = canvas.getContext('2d'),
87-
data,
88-
sy,
89-
ey,
90-
py,
91-
alpha;
92-
canvas.width = 1;
93-
canvas.height = ih;
94-
ctx.drawImage(img, 0, 0);
95-
data = ctx.getImageData(0, 0, 1, ih).data;
96-
// search image edge pixel position in case it is squashed vertically:
97-
sy = 0;
98-
ey = ih;
99-
py = ih;
100-
while (py > sy) {
101-
alpha = data[(py - 1) * 4 + 3];
102-
if (alpha === 0) {
103-
ey = py;
104-
} else {
105-
sy = py;
106-
}
107-
py = (ey + sy) >> 1;
108-
}
109-
return (py / ih) || 1;
75+
// Transform image coordinates, allows to override e.g.
76+
// the canvas orientation based on the orientation option,
77+
// gets canvas, options passed as arguments:
78+
loadImage.transformCoordinates = function () {
79+
return;
11080
};
11181

112-
// Renders image to canvas while working around iOS image scaling bugs:
113-
// https://github.com/blueimp/JavaScript-Load-Image/issues/13
114-
loadImage.renderImageToCanvas = function (img, canvas, width, height) {
115-
var iw = img.width,
116-
ih = img.height,
117-
ctx = canvas.getContext('2d'),
118-
vertSquashRatio,
119-
d = 1024, // size of tiling canvas
120-
tmpCanvas = document.createElement('canvas'),
121-
tmpCtx,
122-
dw,
123-
dh,
124-
dx,
125-
dy,
126-
sx,
127-
sy;
128-
ctx.save();
129-
if (loadImage.detectSubsampling(img)) {
130-
iw /= 2;
131-
ih /= 2;
132-
}
133-
vertSquashRatio = loadImage.detectVerticalSquash(img, ih);
134-
tmpCanvas.width = tmpCanvas.height = d;
135-
tmpCtx = tmpCanvas.getContext('2d');
136-
dw = Math.ceil(d * width / iw);
137-
dh = Math.ceil(d * height / ih / vertSquashRatio);
138-
dy = 0;
139-
sy = 0;
140-
while (sy < ih) {
141-
dx = 0;
142-
sx = 0;
143-
while (sx < iw) {
144-
tmpCtx.clearRect(0, 0, d, d);
145-
tmpCtx.drawImage(img, -sx, -sy);
146-
ctx.drawImage(tmpCanvas, 0, 0, d, d, dx, dy, dw, dh);
147-
sx += d;
148-
dx += dw;
149-
}
150-
sy += d;
151-
dy += dh;
152-
}
153-
ctx.restore();
154-
tmpCanvas = tmpCtx = null;
82+
// Returns transformed options, allows to override e.g.
83+
// coordinate and dimension options based on the orientation:
84+
loadImage.getTransformedOptions = function (options) {
85+
return options;
86+
};
87+
88+
// Canvas render method, allows to override the
89+
// rendering e.g. to work around issues on iOS:
90+
loadImage.renderImageToCanvas = function (
91+
canvas,
92+
img,
93+
sourceX,
94+
sourceY,
95+
sourceWidth,
96+
sourceHeight,
97+
destX,
98+
destY,
99+
destWidth,
100+
destHeight
101+
) {
102+
canvas.getContext('2d').drawImage(
103+
img,
104+
sourceX,
105+
sourceY,
106+
sourceWidth,
107+
sourceHeight,
108+
destX,
109+
destY,
110+
destWidth,
111+
destHeight
112+
);
113+
return canvas;
155114
};
156115

157-
// Scales the given image (img or canvas HTML element)
116+
// This method is used to determine if the target image
117+
// should be a canvas element:
118+
loadImage.hasCanvasOption = function (options) {
119+
return options.canvas || options.crop;
120+
};
121+
122+
// Scales and/or crops the given image (img or canvas HTML element)
158123
// using the given options.
159124
// Returns a canvas object if the browser supports canvas
160-
// and the canvas option is true or a canvas object is passed
161-
// as image, else the scaled image:
125+
// and the hasCanvasOption method returns true or a canvas
126+
// object is passed as image, else the scaled image:
162127
loadImage.scale = function (img, options) {
163128
options = options || {};
164129
var canvas = document.createElement('canvas'),
165-
width = img.width,
166-
height = img.height,
167-
scale = Math.max(
168-
(options.minWidth || width) / width,
169-
(options.minHeight || height) / height
170-
);
171-
if (scale > 1) {
172-
width = Math.ceil(width * scale);
173-
height = Math.ceil(height * scale);
174-
}
175-
scale = Math.min(
176-
(options.maxWidth || width) / width,
177-
(options.maxHeight || height) / height
178-
);
179-
if (scale < 1) {
180-
width = Math.ceil(width * scale);
181-
height = Math.ceil(height * scale);
130+
useCanvas = img.getContext ||
131+
(loadImage.hasCanvasOption(options) && canvas.getContext),
132+
width = img.naturalWidth || img.width,
133+
height = img.naturalHeight || img.height,
134+
destWidth = width,
135+
destHeight = height,
136+
maxWidth,
137+
maxHeight,
138+
minWidth,
139+
minHeight,
140+
sourceWidth,
141+
sourceHeight,
142+
sourceX,
143+
sourceY,
144+
tmp,
145+
scaleUp = function () {
146+
var scale = Math.max(
147+
(minWidth || destWidth) / destWidth,
148+
(minHeight || destHeight) / destHeight
149+
);
150+
if (scale > 1) {
151+
destWidth = Math.ceil(destWidth * scale);
152+
destHeight = Math.ceil(destHeight * scale);
153+
}
154+
},
155+
scaleDown = function () {
156+
var scale = Math.min(
157+
(maxWidth || destWidth) / destWidth,
158+
(maxHeight || destHeight) / destHeight
159+
);
160+
if (scale < 1) {
161+
destWidth = Math.ceil(destWidth * scale);
162+
destHeight = Math.ceil(destHeight * scale);
163+
}
164+
};
165+
if (useCanvas) {
166+
options = loadImage.getTransformedOptions(options);
167+
sourceX = options.left || 0;
168+
sourceY = options.top || 0;
169+
if (options.sourceWidth) {
170+
sourceWidth = options.sourceWidth;
171+
if (options.right !== undefined && options.left === undefined) {
172+
sourceX = width - sourceWidth - options.right;
173+
}
174+
} else {
175+
sourceWidth = width - sourceX - (options.right || 0);
176+
}
177+
if (options.sourceHeight) {
178+
sourceHeight = options.sourceHeight;
179+
if (options.bottom !== undefined && options.top === undefined) {
180+
sourceY = height - sourceHeight - options.bottom;
181+
}
182+
} else {
183+
sourceHeight = height - sourceY - (options.bottom || 0);
184+
}
185+
destWidth = sourceWidth;
186+
destHeight = sourceHeight;
182187
}
183-
if (img.getContext || (options.canvas && canvas.getContext)) {
184-
canvas.width = width;
185-
canvas.height = height;
186-
if (img._type === 'image/jpeg') {
187-
loadImage
188-
.renderImageToCanvas(img, canvas, width, height);
188+
maxWidth = options.maxWidth;
189+
maxHeight = options.maxHeight;
190+
minWidth = options.minWidth;
191+
minHeight = options.minHeight;
192+
if (useCanvas && maxWidth && maxHeight && options.crop) {
193+
destWidth = maxWidth;
194+
destHeight = maxHeight;
195+
tmp = sourceWidth / sourceHeight - maxWidth / maxHeight;
196+
if (tmp < 0) {
197+
sourceHeight = maxHeight * sourceWidth / maxWidth;
198+
if (options.top === undefined && options.bottom === undefined) {
199+
sourceY = (height - sourceHeight) / 2;
200+
}
201+
} else if (tmp > 0) {
202+
sourceWidth = maxWidth * sourceHeight / maxHeight;
203+
if (options.left === undefined && options.right === undefined) {
204+
sourceX = (width - sourceWidth) / 2;
205+
}
206+
}
207+
} else {
208+
if (options.contain || options.cover) {
209+
minWidth = maxWidth = maxWidth || minWidth;
210+
minHeight = maxHeight = maxHeight || minHeight;
211+
}
212+
if (options.cover) {
213+
scaleDown();
214+
scaleUp();
189215
} else {
190-
canvas.getContext('2d')
191-
.drawImage(img, 0, 0, width, height);
216+
scaleUp();
217+
scaleDown();
192218
}
193-
return canvas;
194219
}
195-
img.width = width;
196-
img.height = height;
220+
if (useCanvas) {
221+
canvas.width = destWidth;
222+
canvas.height = destHeight;
223+
loadImage.transformCoordinates(
224+
canvas,
225+
options
226+
);
227+
return loadImage.renderImageToCanvas(
228+
canvas,
229+
img,
230+
sourceX,
231+
sourceY,
232+
sourceWidth,
233+
sourceHeight,
234+
0,
235+
0,
236+
destWidth,
237+
destHeight
238+
);
239+
}
240+
img.width = destWidth;
241+
img.height = destHeight;
197242
return img;
198243
};
199244

@@ -208,12 +253,15 @@
208253
// Loads a given File object via FileReader interface,
209254
// invokes the callback with the event object (load or error).
210255
// The result can be read via event.target.result:
211-
loadImage.readFile = function (file, callback) {
212-
if (window.FileReader && FileReader.prototype.readAsDataURL) {
256+
loadImage.readFile = function (file, callback, method) {
257+
if (window.FileReader) {
213258
var fileReader = new FileReader();
214259
fileReader.onload = fileReader.onerror = callback;
215-
fileReader.readAsDataURL(file);
216-
return fileReader;
260+
method = method || 'readAsDataURL';
261+
if (fileReader[method]) {
262+
fileReader[method](file);
263+
return fileReader;
264+
}
217265
}
218266
return false;
219267
};

0 commit comments

Comments
 (0)