Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.
 
 
 
 
 
 

328 Zeilen
9.1 KiB

  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. /* global define, module, require */
  12. ;(function (factory) {
  13. 'use strict'
  14. if (typeof define === 'function' && define.amd) {
  15. // Register as an anonymous AMD module:
  16. define(['jquery/fileUploader/vendor/blueimp-load-image/js/load-image'], factory)
  17. } else if (typeof module === 'object' && module.exports) {
  18. factory(require('jquery/fileUploader/vendor/blueimp-load-image/js/load-image'))
  19. } else {
  20. // Browser globals:
  21. factory(window.loadImage)
  22. }
  23. })(function (loadImage) {
  24. 'use strict'
  25. var originalTransform = loadImage.transform
  26. loadImage.createCanvas = function (width, height, offscreen) {
  27. if (offscreen && loadImage.global.OffscreenCanvas) {
  28. return new OffscreenCanvas(width, height)
  29. }
  30. var canvas = document.createElement('canvas')
  31. canvas.width = width
  32. canvas.height = height
  33. return canvas
  34. }
  35. loadImage.transform = function (img, options, callback, file, data) {
  36. originalTransform.call(
  37. loadImage,
  38. loadImage.scale(img, options, data),
  39. options,
  40. callback,
  41. file,
  42. data
  43. )
  44. }
  45. // Transform image coordinates, allows to override e.g.
  46. // the canvas orientation based on the orientation option,
  47. // gets canvas, options and data passed as arguments:
  48. loadImage.transformCoordinates = function () {}
  49. // Returns transformed options, allows to override e.g.
  50. // maxWidth, maxHeight and crop options based on the aspectRatio.
  51. // gets img, options, data passed as arguments:
  52. loadImage.getTransformedOptions = function (img, options) {
  53. var aspectRatio = options.aspectRatio
  54. var newOptions
  55. var i
  56. var width
  57. var height
  58. if (!aspectRatio) {
  59. return options
  60. }
  61. newOptions = {}
  62. for (i in options) {
  63. if (Object.prototype.hasOwnProperty.call(options, i)) {
  64. newOptions[i] = options[i]
  65. }
  66. }
  67. newOptions.crop = true
  68. width = img.naturalWidth || img.width
  69. height = img.naturalHeight || img.height
  70. if (width / height > aspectRatio) {
  71. newOptions.maxWidth = height * aspectRatio
  72. newOptions.maxHeight = height
  73. } else {
  74. newOptions.maxWidth = width
  75. newOptions.maxHeight = width / aspectRatio
  76. }
  77. return newOptions
  78. }
  79. // Canvas render method, allows to implement a different rendering algorithm:
  80. loadImage.drawImage = function (
  81. img,
  82. canvas,
  83. sourceX,
  84. sourceY,
  85. sourceWidth,
  86. sourceHeight,
  87. destWidth,
  88. destHeight,
  89. options
  90. ) {
  91. var ctx = canvas.getContext('2d')
  92. if (options.imageSmoothingEnabled === false) {
  93. ctx.msImageSmoothingEnabled = false
  94. ctx.imageSmoothingEnabled = false
  95. } else if (options.imageSmoothingQuality) {
  96. ctx.imageSmoothingQuality = options.imageSmoothingQuality
  97. }
  98. ctx.drawImage(
  99. img,
  100. sourceX,
  101. sourceY,
  102. sourceWidth,
  103. sourceHeight,
  104. 0,
  105. 0,
  106. destWidth,
  107. destHeight
  108. )
  109. return ctx
  110. }
  111. // Determines if the target image should be a canvas element:
  112. loadImage.requiresCanvas = function (options) {
  113. return options.canvas || options.crop || !!options.aspectRatio
  114. }
  115. // Scales and/or crops the given image (img or canvas HTML element)
  116. // using the given options:
  117. loadImage.scale = function (img, options, data) {
  118. // eslint-disable-next-line no-param-reassign
  119. options = options || {}
  120. // eslint-disable-next-line no-param-reassign
  121. data = data || {}
  122. var useCanvas =
  123. img.getContext ||
  124. (loadImage.requiresCanvas(options) &&
  125. !!loadImage.global.HTMLCanvasElement)
  126. var width = img.naturalWidth || img.width
  127. var height = img.naturalHeight || img.height
  128. var destWidth = width
  129. var destHeight = height
  130. var maxWidth
  131. var maxHeight
  132. var minWidth
  133. var minHeight
  134. var sourceWidth
  135. var sourceHeight
  136. var sourceX
  137. var sourceY
  138. var pixelRatio
  139. var downsamplingRatio
  140. var tmp
  141. var canvas
  142. /**
  143. * Scales up image dimensions
  144. */
  145. function scaleUp() {
  146. var scale = Math.max(
  147. (minWidth || destWidth) / destWidth,
  148. (minHeight || destHeight) / destHeight
  149. )
  150. if (scale > 1) {
  151. destWidth *= scale
  152. destHeight *= scale
  153. }
  154. }
  155. /**
  156. * Scales down image dimensions
  157. */
  158. function scaleDown() {
  159. var scale = Math.min(
  160. (maxWidth || destWidth) / destWidth,
  161. (maxHeight || destHeight) / destHeight
  162. )
  163. if (scale < 1) {
  164. destWidth *= scale
  165. destHeight *= scale
  166. }
  167. }
  168. if (useCanvas) {
  169. // eslint-disable-next-line no-param-reassign
  170. options = loadImage.getTransformedOptions(img, options, data)
  171. sourceX = options.left || 0
  172. sourceY = options.top || 0
  173. if (options.sourceWidth) {
  174. sourceWidth = options.sourceWidth
  175. if (options.right !== undefined && options.left === undefined) {
  176. sourceX = width - sourceWidth - options.right
  177. }
  178. } else {
  179. sourceWidth = width - sourceX - (options.right || 0)
  180. }
  181. if (options.sourceHeight) {
  182. sourceHeight = options.sourceHeight
  183. if (options.bottom !== undefined && options.top === undefined) {
  184. sourceY = height - sourceHeight - options.bottom
  185. }
  186. } else {
  187. sourceHeight = height - sourceY - (options.bottom || 0)
  188. }
  189. destWidth = sourceWidth
  190. destHeight = sourceHeight
  191. }
  192. maxWidth = options.maxWidth
  193. maxHeight = options.maxHeight
  194. minWidth = options.minWidth
  195. minHeight = options.minHeight
  196. if (useCanvas && maxWidth && maxHeight && options.crop) {
  197. destWidth = maxWidth
  198. destHeight = maxHeight
  199. tmp = sourceWidth / sourceHeight - maxWidth / maxHeight
  200. if (tmp < 0) {
  201. sourceHeight = (maxHeight * sourceWidth) / maxWidth
  202. if (options.top === undefined && options.bottom === undefined) {
  203. sourceY = (height - sourceHeight) / 2
  204. }
  205. } else if (tmp > 0) {
  206. sourceWidth = (maxWidth * sourceHeight) / maxHeight
  207. if (options.left === undefined && options.right === undefined) {
  208. sourceX = (width - sourceWidth) / 2
  209. }
  210. }
  211. } else {
  212. if (options.contain || options.cover) {
  213. minWidth = maxWidth = maxWidth || minWidth
  214. minHeight = maxHeight = maxHeight || minHeight
  215. }
  216. if (options.cover) {
  217. scaleDown()
  218. scaleUp()
  219. } else {
  220. scaleUp()
  221. scaleDown()
  222. }
  223. }
  224. if (useCanvas) {
  225. pixelRatio = options.pixelRatio
  226. if (
  227. pixelRatio > 1 &&
  228. // Check if the image has not yet had the device pixel ratio applied:
  229. !(
  230. img.style.width &&
  231. Math.floor(parseFloat(img.style.width, 10)) ===
  232. Math.floor(width / pixelRatio)
  233. )
  234. ) {
  235. destWidth *= pixelRatio
  236. destHeight *= pixelRatio
  237. }
  238. // Check if workaround for Chromium orientation crop bug is required:
  239. // https://bugs.chromium.org/p/chromium/issues/detail?id=1074354
  240. if (
  241. loadImage.orientationCropBug &&
  242. !img.getContext &&
  243. (sourceX || sourceY || sourceWidth !== width || sourceHeight !== height)
  244. ) {
  245. // Write the complete source image to an intermediate canvas first:
  246. tmp = img
  247. // eslint-disable-next-line no-param-reassign
  248. img = loadImage.createCanvas(width, height, true)
  249. loadImage.drawImage(
  250. tmp,
  251. img,
  252. 0,
  253. 0,
  254. width,
  255. height,
  256. width,
  257. height,
  258. options
  259. )
  260. }
  261. downsamplingRatio = options.downsamplingRatio
  262. if (
  263. downsamplingRatio > 0 &&
  264. downsamplingRatio < 1 &&
  265. destWidth < sourceWidth &&
  266. destHeight < sourceHeight
  267. ) {
  268. while (sourceWidth * downsamplingRatio > destWidth) {
  269. canvas = loadImage.createCanvas(
  270. sourceWidth * downsamplingRatio,
  271. sourceHeight * downsamplingRatio,
  272. true
  273. )
  274. loadImage.drawImage(
  275. img,
  276. canvas,
  277. sourceX,
  278. sourceY,
  279. sourceWidth,
  280. sourceHeight,
  281. canvas.width,
  282. canvas.height,
  283. options
  284. )
  285. sourceX = 0
  286. sourceY = 0
  287. sourceWidth = canvas.width
  288. sourceHeight = canvas.height
  289. // eslint-disable-next-line no-param-reassign
  290. img = canvas
  291. }
  292. }
  293. canvas = loadImage.createCanvas(destWidth, destHeight)
  294. loadImage.transformCoordinates(canvas, options, data)
  295. if (pixelRatio > 1) {
  296. canvas.style.width = canvas.width / pixelRatio + 'px'
  297. }
  298. loadImage
  299. .drawImage(
  300. img,
  301. canvas,
  302. sourceX,
  303. sourceY,
  304. sourceWidth,
  305. sourceHeight,
  306. destWidth,
  307. destHeight,
  308. options
  309. )
  310. .setTransform(1, 0, 0, 1, 0, 0) // reset to the identity matrix
  311. return canvas
  312. }
  313. img.width = destWidth
  314. img.height = destHeight
  315. return img
  316. }
  317. })