@ -26,31 +26,38 @@
img . onload = function ( event ) {
return loadImage . onload ( img , event , file , callback , options )
}
if ( loadImage . isInstanceOf ( 'Blob' , file ) ||
// Files are also Blob instances, but some browsers
// (Firefox 3.6) support the File API but not Blobs:
loadImage . isInstanceOf ( 'File' , file ) ) {
if ( typeof file === 'string' ) {
loadImage . fetchBlob ( file , function ( blob ) {
if ( blob ) {
file = blob
url = loadImage . createObjectURL ( file )
} else {
url = file
if ( options && options . crossOrigin ) {
img . crossOrigin = options . crossOrigin
}
}
img . src = url
} , options )
return img
} else if ( loadImage . isInstanceOf ( 'Blob' , file ) ||
// Files are also Blob instances, but some browsers
// (Firefox 3.6) support the File API but not Blobs:
loadImage . isInstanceOf ( 'File' , file ) ) {
url = img . _objectURL = loadImage . createObjectURL ( file )
} else if ( typeof file === 'string' ) {
url = file
if ( options && options . crossOrigin ) {
img . crossOrigin = options . crossOrigin
if ( url ) {
img . src = url
return img
}
} else {
return false
}
if ( url ) {
img . src = url
return img
return loadImage . readFile ( file , function ( e ) {
var target = e . target
if ( target && target . result ) {
img . src = target . result
} else if ( callback ) {
callback ( e )
}
} )
}
return loadImage . readFile ( file , function ( e ) {
var target = e . target
if ( target && target . result ) {
img . src = target . result
} else if ( callback ) {
callback ( e )
}
} )
}
// The check for URL.revokeObjectURL fixes an issue with Opera 12,
// which provides URL.createObjectURL but doesn't properly implement it:
@ -65,13 +72,20 @@
}
}
// If the callback given to this function returns a blob, it is used as image
// source instead of the original url and overrides the file argument used in
// the onload and onerror event callbacks:
loadImage . fetchBlob = function ( url , callback , options ) {
callback ( )
}
loadImage . isInstanceOf = function ( type , obj ) {
// Cross-frame instanceof check
return Object . prototype . toString . call ( obj ) === '[object ' + type + ']'
}
loadImage . transform = function ( img , options , callback , file , data ) {
callback ( loadImage . scale ( img , options , data ) , data )
callback ( img , data )
}
loadImage . onerror = function ( img , event , file , callback , options ) {
@ -88,248 +102,6 @@
}
}
// 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
}
loadImage . createObjectURL = function ( file ) {
return urlAPI ? urlAPI . createObjectURL ( file ) : false
}