Actualización

This commit is contained in:
Xes
2025-04-10 11:37:29 +02:00
parent 4bfeadb360
commit 8969cc929d
39112 changed files with 975884 additions and 0 deletions

View File

@@ -0,0 +1,481 @@
/*
* JavaScript Load Image Orientation
* https://github.com/blueimp/JavaScript-Load-Image
*
* Copyright 2013, Sebastian Tschan
* https://blueimp.net
*
* Licensed under the MIT license:
* https://opensource.org/licenses/MIT
*/
/*
Exif orientation values to correctly display the letter F:
1 2
██████ ██████
██ ██
████ ████
██ ██
██ ██
3 4
██ ██
██ ██
████ ████
██ ██
██████ ██████
5 6
██████████ ██
██ ██ ██ ██
██ ██████████
7 8
██ ██████████
██ ██ ██ ██
██████████ ██
*/
/* global define, module, require */
;(function (factory) {
'use strict'
if (typeof define === 'function' && define.amd) {
// Register as an anonymous AMD module:
define(['./load-image', './load-image-scale', './load-image-meta'], factory)
} else if (typeof module === 'object' && module.exports) {
factory(
require('./load-image'),
require('./load-image-scale'),
require('./load-image-meta')
)
} else {
// Browser globals:
factory(window.loadImage)
}
})(function (loadImage) {
'use strict'
var originalTransform = loadImage.transform
var originalRequiresCanvas = loadImage.requiresCanvas
var originalRequiresMetaData = loadImage.requiresMetaData
var originalTransformCoordinates = loadImage.transformCoordinates
var originalGetTransformedOptions = loadImage.getTransformedOptions
;(function ($) {
// Guard for non-browser environments (e.g. server-side rendering):
if (!$.global.document) return
// black+white 3x2 JPEG, with the following meta information set:
// - EXIF Orientation: 6 (Rotated 90° CCW)
// Image data layout (B=black, F=white):
// BFF
// BBB
var testImageURL =
'data:image/jpeg;base64,/9j/4QAiRXhpZgAATU0AKgAAAAgAAQESAAMAAAABAAYAAAA' +
'AAAD/2wCEAAEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBA' +
'QEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQE' +
'BAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAf/AABEIAAIAAwMBEQACEQEDEQH/x' +
'ABRAAEAAAAAAAAAAAAAAAAAAAAKEAEBAQADAQEAAAAAAAAAAAAGBQQDCAkCBwEBAAAAAAA' +
'AAAAAAAAAAAAAABEBAAAAAAAAAAAAAAAAAAAAAP/aAAwDAQACEQMRAD8AG8T9NfSMEVMhQ' +
'voP3fFiRZ+MTHDifa/95OFSZU5OzRzxkyejv8ciEfhSceSXGjS8eSdLnZc2HDm4M3BxcXw' +
'H/9k='
var img = document.createElement('img')
img.onload = function () {
// Check if the browser supports automatic image orientation:
$.orientation = img.width === 2 && img.height === 3
if ($.orientation) {
var canvas = $.createCanvas(1, 1, true)
var ctx = canvas.getContext('2d')
ctx.drawImage(img, 1, 1, 1, 1, 0, 0, 1, 1)
// Check if the source image coordinates (sX, sY, sWidth, sHeight) are
// correctly applied to the auto-orientated image, which should result
// in a white opaque pixel (e.g. in Safari).
// Browsers that show a transparent pixel (e.g. Chromium) fail to crop
// auto-oriented images correctly and require a workaround, e.g.
// drawing the complete source image to an intermediate canvas first.
// See https://bugs.chromium.org/p/chromium/issues/detail?id=1074354
$.orientationCropBug =
ctx.getImageData(0, 0, 1, 1).data.toString() !== '255,255,255,255'
}
}
img.src = testImageURL
})(loadImage)
/**
* Determines if the orientation requires a canvas element.
*
* @param {object} [options] Options object
* @param {boolean} [withMetaData] Is metadata required for orientation
* @returns {boolean} Returns true if orientation requires canvas/meta
*/
function requiresCanvasOrientation(options, withMetaData) {
var orientation = options && options.orientation
return (
// Exif orientation for browsers without automatic image orientation:
(orientation === true && !loadImage.orientation) ||
// Orientation reset for browsers with automatic image orientation:
(orientation === 1 && loadImage.orientation) ||
// Orientation to defined value, requires meta for orientation reset only:
((!withMetaData || loadImage.orientation) &&
orientation > 1 &&
orientation < 9)
)
}
/**
* Determines if the image requires an orientation change.
*
* @param {number} [orientation] Defined orientation value
* @param {number} [autoOrientation] Auto-orientation based on Exif data
* @returns {boolean} Returns true if an orientation change is required
*/
function requiresOrientationChange(orientation, autoOrientation) {
return (
orientation !== autoOrientation &&
((orientation === 1 && autoOrientation > 1 && autoOrientation < 9) ||
(orientation > 1 && orientation < 9))
)
}
/**
* Determines orientation combinations that require a rotation by 180°.
*
* The following is a list of combinations that return true:
*
* 2 (flip) => 5 (rot90,flip), 7 (rot90,flip), 6 (rot90), 8 (rot90)
* 4 (flip) => 5 (rot90,flip), 7 (rot90,flip), 6 (rot90), 8 (rot90)
*
* 5 (rot90,flip) => 2 (flip), 4 (flip), 6 (rot90), 8 (rot90)
* 7 (rot90,flip) => 2 (flip), 4 (flip), 6 (rot90), 8 (rot90)
*
* 6 (rot90) => 2 (flip), 4 (flip), 5 (rot90,flip), 7 (rot90,flip)
* 8 (rot90) => 2 (flip), 4 (flip), 5 (rot90,flip), 7 (rot90,flip)
*
* @param {number} [orientation] Defined orientation value
* @param {number} [autoOrientation] Auto-orientation based on Exif data
* @returns {boolean} Returns true if rotation by 180° is required
*/
function requiresRot180(orientation, autoOrientation) {
if (autoOrientation > 1 && autoOrientation < 9) {
switch (orientation) {
case 2:
case 4:
return autoOrientation > 4
case 5:
case 7:
return autoOrientation % 2 === 0
case 6:
case 8:
return (
autoOrientation === 2 ||
autoOrientation === 4 ||
autoOrientation === 5 ||
autoOrientation === 7
)
}
}
return false
}
// Determines if the target image should be a canvas element:
loadImage.requiresCanvas = function (options) {
return (
requiresCanvasOrientation(options) ||
originalRequiresCanvas.call(loadImage, options)
)
}
// Determines if metadata should be loaded automatically:
loadImage.requiresMetaData = function (options) {
return (
requiresCanvasOrientation(options, true) ||
originalRequiresMetaData.call(loadImage, options)
)
}
loadImage.transform = function (img, options, callback, file, data) {
originalTransform.call(
loadImage,
img,
options,
function (img, data) {
if (data) {
var autoOrientation =
loadImage.orientation && data.exif && data.exif.get('Orientation')
if (autoOrientation > 4 && autoOrientation < 9) {
// Automatic image orientation switched image dimensions
var originalWidth = data.originalWidth
var originalHeight = data.originalHeight
data.originalWidth = originalHeight
data.originalHeight = originalWidth
}
}
callback(img, data)
},
file,
data
)
}
// Transforms coordinate and dimension options
// based on the given orientation option:
loadImage.getTransformedOptions = function (img, opts, data) {
var options = originalGetTransformedOptions.call(loadImage, img, opts)
var exifOrientation = data.exif && data.exif.get('Orientation')
var orientation = options.orientation
var autoOrientation = loadImage.orientation && exifOrientation
if (orientation === true) orientation = exifOrientation
if (!requiresOrientationChange(orientation, autoOrientation)) {
return options
}
var top = options.top
var right = options.right
var bottom = options.bottom
var left = options.left
var newOptions = {}
for (var i in options) {
if (Object.prototype.hasOwnProperty.call(options, i)) {
newOptions[i] = options[i]
}
}
newOptions.orientation = orientation
if (
(orientation > 4 && !(autoOrientation > 4)) ||
(orientation < 5 && autoOrientation > 4)
) {
// Image dimensions and target dimensions are switched
newOptions.maxWidth = options.maxHeight
newOptions.maxHeight = options.maxWidth
newOptions.minWidth = options.minHeight
newOptions.minHeight = options.minWidth
newOptions.sourceWidth = options.sourceHeight
newOptions.sourceHeight = options.sourceWidth
}
if (autoOrientation > 1) {
// Browsers which correctly apply source image coordinates to
// auto-oriented images
switch (autoOrientation) {
case 2:
// Horizontal flip
right = options.left
left = options.right
break
case 3:
// 180° Rotate CCW
top = options.bottom
right = options.left
bottom = options.top
left = options.right
break
case 4:
// Vertical flip
top = options.bottom
bottom = options.top
break
case 5:
// Horizontal flip + 90° Rotate CCW
top = options.left
right = options.bottom
bottom = options.right
left = options.top
break
case 6:
// 90° Rotate CCW
top = options.left
right = options.top
bottom = options.right
left = options.bottom
break
case 7:
// Vertical flip + 90° Rotate CCW
top = options.right
right = options.top
bottom = options.left
left = options.bottom
break
case 8:
// 90° Rotate CW
top = options.right
right = options.bottom
bottom = options.left
left = options.top
break
}
// Some orientation combinations require additional rotation by 180°:
if (requiresRot180(orientation, autoOrientation)) {
var tmpTop = top
var tmpRight = right
top = bottom
right = left
bottom = tmpTop
left = tmpRight
}
}
newOptions.top = top
newOptions.right = right
newOptions.bottom = bottom
newOptions.left = left
// Account for defined browser orientation:
switch (orientation) {
case 2:
// Horizontal flip
newOptions.right = left
newOptions.left = right
break
case 3:
// 180° Rotate CCW
newOptions.top = bottom
newOptions.right = left
newOptions.bottom = top
newOptions.left = right
break
case 4:
// Vertical flip
newOptions.top = bottom
newOptions.bottom = top
break
case 5:
// Vertical flip + 90° Rotate CW
newOptions.top = left
newOptions.right = bottom
newOptions.bottom = right
newOptions.left = top
break
case 6:
// 90° Rotate CW
newOptions.top = right
newOptions.right = bottom
newOptions.bottom = left
newOptions.left = top
break
case 7:
// Horizontal flip + 90° Rotate CW
newOptions.top = right
newOptions.right = top
newOptions.bottom = left
newOptions.left = bottom
break
case 8:
// 90° Rotate CCW
newOptions.top = left
newOptions.right = top
newOptions.bottom = right
newOptions.left = bottom
break
}
return newOptions
}
// Transform image orientation based on the given EXIF orientation option:
loadImage.transformCoordinates = function (canvas, options, data) {
originalTransformCoordinates.call(loadImage, canvas, options, data)
var orientation = options.orientation
var autoOrientation =
loadImage.orientation && data.exif && data.exif.get('Orientation')
if (!requiresOrientationChange(orientation, autoOrientation)) {
return
}
var ctx = canvas.getContext('2d')
var width = canvas.width
var height = canvas.height
var sourceWidth = width
var sourceHeight = height
if (
(orientation > 4 && !(autoOrientation > 4)) ||
(orientation < 5 && autoOrientation > 4)
) {
// Image dimensions and target dimensions are switched
canvas.width = height
canvas.height = width
}
if (orientation > 4) {
// Destination and source dimensions are switched
sourceWidth = height
sourceHeight = width
}
// Reset automatic browser orientation:
switch (autoOrientation) {
case 2:
// Horizontal flip
ctx.translate(sourceWidth, 0)
ctx.scale(-1, 1)
break
case 3:
// 180° Rotate CCW
ctx.translate(sourceWidth, sourceHeight)
ctx.rotate(Math.PI)
break
case 4:
// Vertical flip
ctx.translate(0, sourceHeight)
ctx.scale(1, -1)
break
case 5:
// Horizontal flip + 90° Rotate CCW
ctx.rotate(-0.5 * Math.PI)
ctx.scale(-1, 1)
break
case 6:
// 90° Rotate CCW
ctx.rotate(-0.5 * Math.PI)
ctx.translate(-sourceWidth, 0)
break
case 7:
// Vertical flip + 90° Rotate CCW
ctx.rotate(-0.5 * Math.PI)
ctx.translate(-sourceWidth, sourceHeight)
ctx.scale(1, -1)
break
case 8:
// 90° Rotate CW
ctx.rotate(0.5 * Math.PI)
ctx.translate(0, -sourceHeight)
break
}
// Some orientation combinations require additional rotation by 180°:
if (requiresRot180(orientation, autoOrientation)) {
ctx.translate(sourceWidth, sourceHeight)
ctx.rotate(Math.PI)
}
switch (orientation) {
case 2:
// Horizontal flip
ctx.translate(width, 0)
ctx.scale(-1, 1)
break
case 3:
// 180° Rotate CCW
ctx.translate(width, height)
ctx.rotate(Math.PI)
break
case 4:
// Vertical flip
ctx.translate(0, height)
ctx.scale(1, -1)
break
case 5:
// Vertical flip + 90° Rotate CW
ctx.rotate(0.5 * Math.PI)
ctx.scale(1, -1)
break
case 6:
// 90° Rotate CW
ctx.rotate(0.5 * Math.PI)
ctx.translate(0, -height)
break
case 7:
// Horizontal flip + 90° Rotate CW
ctx.rotate(0.5 * Math.PI)
ctx.translate(width, -height)
ctx.scale(-1, 1)
break
case 8:
// 90° Rotate CCW
ctx.rotate(-0.5 * Math.PI)
ctx.translate(-width, 0)
break
}
}
})