load-image-orientation.js 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. /*
  2. * JavaScript Load Image Orientation
  3. * https://github.com/blueimp/JavaScript-Load-Image
  4. *
  5. * Copyright 2013, 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(['./load-image', './load-image-scale', './load-image-meta'], factory)
  17. } else if (typeof module === 'object' && module.exports) {
  18. factory(
  19. require('./load-image'),
  20. require('./load-image-scale'),
  21. require('./load-image-meta')
  22. )
  23. } else {
  24. // Browser globals:
  25. factory(window.loadImage)
  26. }
  27. })(function(loadImage) {
  28. 'use strict'
  29. var originalHasCanvasOption = loadImage.hasCanvasOption
  30. var originalHasMetaOption = loadImage.hasMetaOption
  31. var originalTransformCoordinates = loadImage.transformCoordinates
  32. var originalGetTransformedOptions = loadImage.getTransformedOptions
  33. // Determines if the target image should be a canvas element:
  34. loadImage.hasCanvasOption = function(options) {
  35. return (
  36. !!options.orientation || originalHasCanvasOption.call(loadImage, options)
  37. )
  38. }
  39. // Determines if meta data should be loaded automatically:
  40. loadImage.hasMetaOption = function(options) {
  41. return (
  42. (options && options.orientation === true) ||
  43. originalHasMetaOption.call(loadImage, options)
  44. )
  45. }
  46. // Transform image orientation based on
  47. // the given EXIF orientation option:
  48. loadImage.transformCoordinates = function(canvas, options) {
  49. originalTransformCoordinates.call(loadImage, canvas, options)
  50. var ctx = canvas.getContext('2d')
  51. var width = canvas.width
  52. var height = canvas.height
  53. var styleWidth = canvas.style.width
  54. var styleHeight = canvas.style.height
  55. var orientation = options.orientation
  56. if (!orientation || orientation > 8) {
  57. return
  58. }
  59. if (orientation > 4) {
  60. canvas.width = height
  61. canvas.height = width
  62. canvas.style.width = styleHeight
  63. canvas.style.height = styleWidth
  64. }
  65. switch (orientation) {
  66. case 2:
  67. // horizontal flip
  68. ctx.translate(width, 0)
  69. ctx.scale(-1, 1)
  70. break
  71. case 3:
  72. // 180° rotate left
  73. ctx.translate(width, height)
  74. ctx.rotate(Math.PI)
  75. break
  76. case 4:
  77. // vertical flip
  78. ctx.translate(0, height)
  79. ctx.scale(1, -1)
  80. break
  81. case 5:
  82. // vertical flip + 90 rotate right
  83. ctx.rotate(0.5 * Math.PI)
  84. ctx.scale(1, -1)
  85. break
  86. case 6:
  87. // 90° rotate right
  88. ctx.rotate(0.5 * Math.PI)
  89. ctx.translate(0, -height)
  90. break
  91. case 7:
  92. // horizontal flip + 90 rotate right
  93. ctx.rotate(0.5 * Math.PI)
  94. ctx.translate(width, -height)
  95. ctx.scale(-1, 1)
  96. break
  97. case 8:
  98. // 90° rotate left
  99. ctx.rotate(-0.5 * Math.PI)
  100. ctx.translate(-width, 0)
  101. break
  102. }
  103. }
  104. // Transforms coordinate and dimension options
  105. // based on the given orientation option:
  106. loadImage.getTransformedOptions = function(img, opts, data) {
  107. var options = originalGetTransformedOptions.call(loadImage, img, opts)
  108. var orientation = options.orientation
  109. var newOptions
  110. var i
  111. if (orientation === true && data && data.exif) {
  112. orientation = data.exif.get('Orientation')
  113. }
  114. if (!orientation || orientation > 8 || orientation === 1) {
  115. return options
  116. }
  117. newOptions = {}
  118. for (i in options) {
  119. if (Object.prototype.hasOwnProperty.call(options, i)) {
  120. newOptions[i] = options[i]
  121. }
  122. }
  123. newOptions.orientation = orientation
  124. switch (orientation) {
  125. case 2:
  126. // horizontal flip
  127. newOptions.left = options.right
  128. newOptions.right = options.left
  129. break
  130. case 3:
  131. // 180° rotate left
  132. newOptions.left = options.right
  133. newOptions.top = options.bottom
  134. newOptions.right = options.left
  135. newOptions.bottom = options.top
  136. break
  137. case 4:
  138. // vertical flip
  139. newOptions.top = options.bottom
  140. newOptions.bottom = options.top
  141. break
  142. case 5:
  143. // vertical flip + 90 rotate right
  144. newOptions.left = options.top
  145. newOptions.top = options.left
  146. newOptions.right = options.bottom
  147. newOptions.bottom = options.right
  148. break
  149. case 6:
  150. // 90° rotate right
  151. newOptions.left = options.top
  152. newOptions.top = options.right
  153. newOptions.right = options.bottom
  154. newOptions.bottom = options.left
  155. break
  156. case 7:
  157. // horizontal flip + 90 rotate right
  158. newOptions.left = options.bottom
  159. newOptions.top = options.right
  160. newOptions.right = options.top
  161. newOptions.bottom = options.left
  162. break
  163. case 8:
  164. // 90° rotate left
  165. newOptions.left = options.bottom
  166. newOptions.top = options.left
  167. newOptions.right = options.top
  168. newOptions.bottom = options.right
  169. break
  170. }
  171. if (newOptions.orientation > 4) {
  172. newOptions.maxWidth = options.maxHeight
  173. newOptions.maxHeight = options.maxWidth
  174. newOptions.minWidth = options.minHeight
  175. newOptions.minHeight = options.minWidth
  176. newOptions.sourceWidth = options.sourceHeight
  177. newOptions.sourceHeight = options.sourceWidth
  178. }
  179. return newOptions
  180. }
  181. })