283 lines
7.6 KiB
JavaScript
283 lines
7.6 KiB
JavaScript
|
/*
|
||
|
* JavaScript Load Image Scaling
|
||
|
* https://github.com/blueimp/JavaScript-Load-Image
|
||
|
*
|
||
|
* Copyright 2011, Sebastian Tschan
|
||
|
* https://blueimp.net
|
||
|
*
|
||
|
* Licensed under the MIT license:
|
||
|
* https://opensource.org/licenses/MIT
|
||
|
*/
|
||
|
|
||
|
/* global define */
|
||
|
|
||
|
;(function (factory) {
|
||
|
'use strict'
|
||
|
if (typeof define === 'function' && define.amd) {
|
||
|
// Register as an anonymous AMD module:
|
||
|
define(['./load-image'], factory)
|
||
|
} else if (typeof module === 'object' && module.exports) {
|
||
|
factory(require('./load-image'))
|
||
|
} else {
|
||
|
// Browser globals:
|
||
|
factory(window.loadImage)
|
||
|
}
|
||
|
}(function (loadImage) {
|
||
|
'use strict'
|
||
|
|
||
|
var originalTransform = loadImage.transform
|
||
|
|
||
|
loadImage.transform = function (img, options, callback, file, data) {
|
||
|
originalTransform.call(
|
||
|
loadImage,
|
||
|
loadImage.scale(img, options, data),
|
||
|
options,
|
||
|
callback,
|
||
|
file,
|
||
|
data
|
||
|
)
|
||
|
}
|
||
|
|
||
|
// Transform image coordinates, allows to override e.g.
|
||
|
// the canvas orientation based on the orientation option,
|
||
|
// gets canvas, options passed as arguments:
|
||
|
loadImage.transformCoordinates = function () {
|
||
|
return
|
||
|
}
|
||
|
|
||
|
// Returns transformed options, allows to override e.g.
|
||
|
// maxWidth, maxHeight and crop options based on the aspectRatio.
|
||
|
// gets img, options passed as arguments:
|
||
|
loadImage.getTransformedOptions = function (img, options) {
|
||
|
var aspectRatio = options.aspectRatio
|
||
|
var newOptions
|
||
|
var i
|
||
|
var width
|
||
|
var height
|
||
|
if (!aspectRatio) {
|
||
|
return options
|
||
|
}
|
||
|
newOptions = {}
|
||
|
for (i in options) {
|
||
|
if (options.hasOwnProperty(i)) {
|
||
|
newOptions[i] = options[i]
|
||
|
}
|
||
|
}
|
||
|
newOptions.crop = true
|
||
|
width = img.naturalWidth || img.width
|
||
|
height = img.naturalHeight || img.height
|
||
|
if (width / height > aspectRatio) {
|
||
|
newOptions.maxWidth = height * aspectRatio
|
||
|
newOptions.maxHeight = height
|
||
|
} else {
|
||
|
newOptions.maxWidth = width
|
||
|
newOptions.maxHeight = width / aspectRatio
|
||
|
}
|
||
|
return newOptions
|
||
|
}
|
||
|
|
||
|
// Canvas render method, allows to implement a different rendering algorithm:
|
||
|
loadImage.renderImageToCanvas = function (
|
||
|
canvas,
|
||
|
img,
|
||
|
sourceX,
|
||
|
sourceY,
|
||
|
sourceWidth,
|
||
|
sourceHeight,
|
||
|
destX,
|
||
|
destY,
|
||
|
destWidth,
|
||
|
destHeight
|
||
|
) {
|
||
|
canvas.getContext('2d').drawImage(
|
||
|
img,
|
||
|
sourceX,
|
||
|
sourceY,
|
||
|
sourceWidth,
|
||
|
sourceHeight,
|
||
|
destX,
|
||
|
destY,
|
||
|
destWidth,
|
||
|
destHeight
|
||
|
)
|
||
|
return canvas
|
||
|
}
|
||
|
|
||
|
// Determines if the target image should be a canvas element:
|
||
|
loadImage.hasCanvasOption = function (options) {
|
||
|
return options.canvas || options.crop || !!options.aspectRatio
|
||
|
}
|
||
|
|
||
|
// Scales and/or crops the given image (img or canvas HTML element)
|
||
|
// using the given options.
|
||
|
// Returns a canvas object if the browser supports canvas
|
||
|
// and the hasCanvasOption method returns true or a canvas
|
||
|
// object is passed as image, else the scaled image:
|
||
|
loadImage.scale = function (img, options, data) {
|
||
|
options = options || {}
|
||
|
var canvas = document.createElement('canvas')
|
||
|
var useCanvas = img.getContext ||
|
||
|
(loadImage.hasCanvasOption(options) && canvas.getContext)
|
||
|
var width = img.naturalWidth || img.width
|
||
|
var height = img.naturalHeight || img.height
|
||
|
var destWidth = width
|
||
|
var destHeight = height
|
||
|
var maxWidth
|
||
|
var maxHeight
|
||
|
var minWidth
|
||
|
var minHeight
|
||
|
var sourceWidth
|
||
|
var sourceHeight
|
||
|
var sourceX
|
||
|
var sourceY
|
||
|
var pixelRatio
|
||
|
var downsamplingRatio
|
||
|
var tmp
|
||
|
function scaleUp () {
|
||
|
var scale = Math.max(
|
||
|
(minWidth || destWidth) / destWidth,
|
||
|
(minHeight || destHeight) / destHeight
|
||
|
)
|
||
|
if (scale > 1) {
|
||
|
destWidth *= scale
|
||
|
destHeight *= scale
|
||
|
}
|
||
|
}
|
||
|
function scaleDown () {
|
||
|
var scale = Math.min(
|
||
|
(maxWidth || destWidth) / destWidth,
|
||
|
(maxHeight || destHeight) / destHeight
|
||
|
)
|
||
|
if (scale < 1) {
|
||
|
destWidth *= scale
|
||
|
destHeight *= scale
|
||
|
}
|
||
|
}
|
||
|
if (useCanvas) {
|
||
|
options = loadImage.getTransformedOptions(img, options, data)
|
||
|
sourceX = options.left || 0
|
||
|
sourceY = options.top || 0
|
||
|
if (options.sourceWidth) {
|
||
|
sourceWidth = options.sourceWidth
|
||
|
if (options.right !== undefined && options.left === undefined) {
|
||
|
sourceX = width - sourceWidth - options.right
|
||
|
}
|
||
|
} else {
|
||
|
sourceWidth = width - sourceX - (options.right || 0)
|
||
|
}
|
||
|
if (options.sourceHeight) {
|
||
|
sourceHeight = options.sourceHeight
|
||
|
if (options.bottom !== undefined && options.top === undefined) {
|
||
|
sourceY = height - sourceHeight - options.bottom
|
||
|
}
|
||
|
} else {
|
||
|
sourceHeight = height - sourceY - (options.bottom || 0)
|
||
|
}
|
||
|
destWidth = sourceWidth
|
||
|
destHeight = sourceHeight
|
||
|
}
|
||
|
maxWidth = options.maxWidth
|
||
|
maxHeight = options.maxHeight
|
||
|
minWidth = options.minWidth
|
||
|
minHeight = options.minHeight
|
||
|
if (useCanvas && maxWidth && maxHeight && options.crop) {
|
||
|
destWidth = maxWidth
|
||
|
destHeight = maxHeight
|
||
|
tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
|
||
|
if (tmp < 0) {
|
||
|
sourceHeight = maxHeight * sourceWidth / maxWidth
|
||
|
if (options.top === undefined && options.bottom === undefined) {
|
||
|
sourceY = (height - sourceHeight) / 2
|
||
|
}
|
||
|
} else if (tmp > 0) {
|
||
|
sourceWidth = maxWidth * sourceHeight / maxHeight
|
||
|
if (options.left === undefined && options.right === undefined) {
|
||
|
sourceX = (width - sourceWidth) / 2
|
||
|
}
|
||
|
}
|
||
|
} else {
|
||
|
if (options.contain || options.cover) {
|
||
|
minWidth = maxWidth = maxWidth || minWidth
|
||
|
minHeight = maxHeight = maxHeight || minHeight
|
||
|
}
|
||
|
if (options.cover) {
|
||
|
scaleDown()
|
||
|
scaleUp()
|
||
|
} else {
|
||
|
scaleUp()
|
||
|
scaleDown()
|
||
|
}
|
||
|
}
|
||
|
if (useCanvas) {
|
||
|
pixelRatio = options.pixelRatio
|
||
|
if (pixelRatio > 1) {
|
||
|
canvas.style.width = destWidth + 'px'
|
||
|
canvas.style.height = destHeight + 'px'
|
||
|
destWidth *= pixelRatio
|
||
|
destHeight *= pixelRatio
|
||
|
canvas.getContext('2d').scale(pixelRatio, pixelRatio)
|
||
|
}
|
||
|
downsamplingRatio = options.downsamplingRatio
|
||
|
if (downsamplingRatio > 0 && downsamplingRatio < 1 &&
|
||
|
destWidth < sourceWidth && destHeight < sourceHeight) {
|
||
|
while (sourceWidth * downsamplingRatio > destWidth) {
|
||
|
canvas.width = sourceWidth * downsamplingRatio
|
||
|
canvas.height = sourceHeight * downsamplingRatio
|
||
|
loadImage.renderImageToCanvas(
|
||
|
canvas,
|
||
|
img,
|
||
|
sourceX,
|
||
|
sourceY,
|
||
|
sourceWidth,
|
||
|
sourceHeight,
|
||
|
0,
|
||
|
0,
|
||
|
canvas.width,
|
||
|
canvas.height
|
||
|
)
|
||
|
sourceX = 0
|
||
|
sourceY = 0
|
||
|
sourceWidth = canvas.width
|
||
|
sourceHeight = canvas.height
|
||
|
img = document.createElement('canvas')
|
||
|
img.width = sourceWidth
|
||
|
img.height = sourceHeight
|
||
|
loadImage.renderImageToCanvas(
|
||
|
img,
|
||
|
canvas,
|
||
|
0,
|
||
|
0,
|
||
|
sourceWidth,
|
||
|
sourceHeight,
|
||
|
0,
|
||
|
0,
|
||
|
sourceWidth,
|
||
|
sourceHeight
|
||
|
)
|
||
|
}
|
||
|
}
|
||
|
canvas.width = destWidth
|
||
|
canvas.height = destHeight
|
||
|
loadImage.transformCoordinates(
|
||
|
canvas,
|
||
|
options
|
||
|
)
|
||
|
return loadImage.renderImageToCanvas(
|
||
|
canvas,
|
||
|
img,
|
||
|
sourceX,
|
||
|
sourceY,
|
||
|
sourceWidth,
|
||
|
sourceHeight,
|
||
|
0,
|
||
|
0,
|
||
|
destWidth,
|
||
|
destHeight
|
||
|
)
|
||
|
}
|
||
|
img.width = destWidth
|
||
|
img.height = destHeight
|
||
|
return img
|
||
|
}
|
||
|
}))
|