Skip to content

Commit cad8a5a

Browse files
committed
Move image scaling functionality into a separate module.
1 parent a3eef97 commit cad8a5a

File tree

7 files changed

+291
-248
lines changed

7 files changed

+291
-248
lines changed

README.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,11 @@ Or alternatively, choose which components you want to include:
4141

4242
```html
4343
<script src="js/load-image.js"></script>
44-
<script src="js/load-image-orientation.js"></script>
44+
<script src="js/load-image-scale.js"></script>
4545
<script src="js/load-image-meta.js"></script>
4646
<script src="js/load-image-exif.js"></script>
4747
<script src="js/load-image-exif-map.js"></script>
48+
<script src="js/load-image-orientation.js"></script>
4849
```
4950

5051
## Usage
@@ -200,7 +201,7 @@ value `true`.
200201
When set to `true`, it will set the orientation value based on the EXIF data of
201202
the image, which will be parsed automatically if the exif library is available.
202203
Setting the `orientation` also enables the `canvas` option.
203-
Setting `orientation` to `true` alsoe enables the `meta` option.
204+
Setting `orientation` to `true` also enables the `meta` option.
204205
* **meta**: Automatically parses the image meta data if set to `true`.
205206
The meta data is passed to the callback as second argument.
206207
* **canvas**: Returns the image as

index.html

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ <h2>Exif meta data</h2>
5757
</div>
5858
<br>
5959
<script src="js/load-image.js"></script>
60+
<script src="js/load-image-scale.js"></script>
6061
<script src="js/load-image-meta.js"></script>
6162
<script src="js/load-image-exif.js"></script>
6263
<script src="js/load-image-exif-map.js"></script>

js/load-image-orientation.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
'use strict'
1616
if (typeof define === 'function' && define.amd) {
1717
// Register as an anonymous AMD module:
18-
define(['./load-image'], factory)
18+
define(['./load-image', './load-image-scale'], factory)
1919
} else if (typeof module === 'object' && module.exports) {
20-
factory(require('./load-image'))
20+
factory(require('./load-image'), require('./load-image-scale'))
2121
} else {
2222
// Browser globals:
2323
factory(window.loadImage)

js/load-image-scale.js

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
/*
2+
* JavaScript Load Image Scaling
3+
* https://github.com/blueimp/JavaScript-Load-Image
4+
*
5+
* Copyright 2011, Sebastian Tschan
6+
* https://blueimp.net
7+
*
8+
* Licensed under the MIT license:
9+
* https://opensource.org/licenses/MIT
10+
*/
11+
12+
/* global define */
13+
14+
;(function (factory) {
15+
'use strict'
16+
if (typeof define === 'function' && define.amd) {
17+
// Register as an anonymous AMD module:
18+
define(['./load-image'], factory)
19+
} else if (typeof module === 'object' && module.exports) {
20+
factory(require('./load-image'))
21+
} else {
22+
// Browser globals:
23+
factory(window.loadImage)
24+
}
25+
}(function (loadImage) {
26+
'use strict'
27+
28+
var originalTransform = loadImage.transform
29+
30+
loadImage.transform = function (img, options, callback, file, data) {
31+
originalTransform.call(
32+
loadImage,
33+
loadImage.scale(img, options, data),
34+
options,
35+
callback,
36+
file,
37+
data
38+
)
39+
}
40+
41+
// Transform image coordinates, allows to override e.g.
42+
// the canvas orientation based on the orientation option,
43+
// gets canvas, options passed as arguments:
44+
loadImage.transformCoordinates = function () {
45+
return
46+
}
47+
48+
// Returns transformed options, allows to override e.g.
49+
// maxWidth, maxHeight and crop options based on the aspectRatio.
50+
// gets img, options passed as arguments:
51+
loadImage.getTransformedOptions = function (img, options) {
52+
var aspectRatio = options.aspectRatio
53+
var newOptions
54+
var i
55+
var width
56+
var height
57+
if (!aspectRatio) {
58+
return options
59+
}
60+
newOptions = {}
61+
for (i in options) {
62+
if (options.hasOwnProperty(i)) {
63+
newOptions[i] = options[i]
64+
}
65+
}
66+
newOptions.crop = true
67+
width = img.naturalWidth || img.width
68+
height = img.naturalHeight || img.height
69+
if (width / height > aspectRatio) {
70+
newOptions.maxWidth = height * aspectRatio
71+
newOptions.maxHeight = height
72+
} else {
73+
newOptions.maxWidth = width
74+
newOptions.maxHeight = width / aspectRatio
75+
}
76+
return newOptions
77+
}
78+
79+
// Canvas render method, allows to implement a different rendering algorithm:
80+
loadImage.renderImageToCanvas = function (
81+
canvas,
82+
img,
83+
sourceX,
84+
sourceY,
85+
sourceWidth,
86+
sourceHeight,
87+
destX,
88+
destY,
89+
destWidth,
90+
destHeight
91+
) {
92+
canvas.getContext('2d').drawImage(
93+
img,
94+
sourceX,
95+
sourceY,
96+
sourceWidth,
97+
sourceHeight,
98+
destX,
99+
destY,
100+
destWidth,
101+
destHeight
102+
)
103+
return canvas
104+
}
105+
106+
// Determines if the target image should be a canvas element:
107+
loadImage.hasCanvasOption = function (options) {
108+
return options.canvas || options.crop || !!options.aspectRatio
109+
}
110+
111+
// Scales and/or crops the given image (img or canvas HTML element)
112+
// using the given options.
113+
// Returns a canvas object if the browser supports canvas
114+
// and the hasCanvasOption method returns true or a canvas
115+
// object is passed as image, else the scaled image:
116+
loadImage.scale = function (img, options, data) {
117+
options = options || {}
118+
var canvas = document.createElement('canvas')
119+
var useCanvas = img.getContext ||
120+
(loadImage.hasCanvasOption(options) && canvas.getContext)
121+
var width = img.naturalWidth || img.width
122+
var height = img.naturalHeight || img.height
123+
var destWidth = width
124+
var destHeight = height
125+
var maxWidth
126+
var maxHeight
127+
var minWidth
128+
var minHeight
129+
var sourceWidth
130+
var sourceHeight
131+
var sourceX
132+
var sourceY
133+
var pixelRatio
134+
var downsamplingRatio
135+
var tmp
136+
function scaleUp () {
137+
var scale = Math.max(
138+
(minWidth || destWidth) / destWidth,
139+
(minHeight || destHeight) / destHeight
140+
)
141+
if (scale > 1) {
142+
destWidth *= scale
143+
destHeight *= scale
144+
}
145+
}
146+
function scaleDown () {
147+
var scale = Math.min(
148+
(maxWidth || destWidth) / destWidth,
149+
(maxHeight || destHeight) / destHeight
150+
)
151+
if (scale < 1) {
152+
destWidth *= scale
153+
destHeight *= scale
154+
}
155+
}
156+
if (useCanvas) {
157+
options = loadImage.getTransformedOptions(img, options, data)
158+
sourceX = options.left || 0
159+
sourceY = options.top || 0
160+
if (options.sourceWidth) {
161+
sourceWidth = options.sourceWidth
162+
if (options.right !== undefined && options.left === undefined) {
163+
sourceX = width - sourceWidth - options.right
164+
}
165+
} else {
166+
sourceWidth = width - sourceX - (options.right || 0)
167+
}
168+
if (options.sourceHeight) {
169+
sourceHeight = options.sourceHeight
170+
if (options.bottom !== undefined && options.top === undefined) {
171+
sourceY = height - sourceHeight - options.bottom
172+
}
173+
} else {
174+
sourceHeight = height - sourceY - (options.bottom || 0)
175+
}
176+
destWidth = sourceWidth
177+
destHeight = sourceHeight
178+
}
179+
maxWidth = options.maxWidth
180+
maxHeight = options.maxHeight
181+
minWidth = options.minWidth
182+
minHeight = options.minHeight
183+
if (useCanvas && maxWidth && maxHeight && options.crop) {
184+
destWidth = maxWidth
185+
destHeight = maxHeight
186+
tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
187+
if (tmp < 0) {
188+
sourceHeight = maxHeight * sourceWidth / maxWidth
189+
if (options.top === undefined && options.bottom === undefined) {
190+
sourceY = (height - sourceHeight) / 2
191+
}
192+
} else if (tmp > 0) {
193+
sourceWidth = maxWidth * sourceHeight / maxHeight
194+
if (options.left === undefined && options.right === undefined) {
195+
sourceX = (width - sourceWidth) / 2
196+
}
197+
}
198+
} else {
199+
if (options.contain || options.cover) {
200+
minWidth = maxWidth = maxWidth || minWidth
201+
minHeight = maxHeight = maxHeight || minHeight
202+
}
203+
if (options.cover) {
204+
scaleDown()
205+
scaleUp()
206+
} else {
207+
scaleUp()
208+
scaleDown()
209+
}
210+
}
211+
if (useCanvas) {
212+
pixelRatio = options.pixelRatio
213+
if (pixelRatio > 1) {
214+
canvas.style.width = destWidth + 'px'
215+
canvas.style.height = destHeight + 'px'
216+
destWidth *= pixelRatio
217+
destHeight *= pixelRatio
218+
canvas.getContext('2d').scale(pixelRatio, pixelRatio)
219+
}
220+
downsamplingRatio = options.downsamplingRatio
221+
if (downsamplingRatio > 0 && downsamplingRatio < 1 &&
222+
destWidth < sourceWidth && destHeight < sourceHeight) {
223+
while (sourceWidth * downsamplingRatio > destWidth) {
224+
canvas.width = sourceWidth * downsamplingRatio
225+
canvas.height = sourceHeight * downsamplingRatio
226+
loadImage.renderImageToCanvas(
227+
canvas,
228+
img,
229+
sourceX,
230+
sourceY,
231+
sourceWidth,
232+
sourceHeight,
233+
0,
234+
0,
235+
canvas.width,
236+
canvas.height
237+
)
238+
sourceX = 0
239+
sourceY = 0
240+
sourceWidth = canvas.width
241+
sourceHeight = canvas.height
242+
img = document.createElement('canvas')
243+
img.width = sourceWidth
244+
img.height = sourceHeight
245+
loadImage.renderImageToCanvas(
246+
img,
247+
canvas,
248+
0,
249+
0,
250+
sourceWidth,
251+
sourceHeight,
252+
0,
253+
0,
254+
sourceWidth,
255+
sourceHeight
256+
)
257+
}
258+
}
259+
canvas.width = destWidth
260+
canvas.height = destHeight
261+
loadImage.transformCoordinates(
262+
canvas,
263+
options
264+
)
265+
return loadImage.renderImageToCanvas(
266+
canvas,
267+
img,
268+
sourceX,
269+
sourceY,
270+
sourceWidth,
271+
sourceHeight,
272+
0,
273+
0,
274+
destWidth,
275+
destHeight
276+
)
277+
}
278+
img.width = destWidth
279+
img.height = destHeight
280+
return img
281+
}
282+
}))

0 commit comments

Comments
 (0)