Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.
 
 
 
 
 
 

347 řádky
11 KiB

  1. /*
  2. * jQuery File Upload Image Preview & Resize Plugin
  3. * https://github.com/blueimp/jQuery-File-Upload
  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, require */
  12. (function (factory) {
  13. 'use strict';
  14. if (typeof define === 'function' && define.amd) {
  15. // Register as an anonymous AMD module:
  16. define([
  17. 'jquery',
  18. 'jquery/fileUploader/vendor/blueimp-load-image/js/load-image',
  19. 'jquery/fileUploader/vendor/blueimp-load-image/js/load-image-meta',
  20. 'jquery/fileUploader/vendor/blueimp-load-image/js/load-image-scale',
  21. 'jquery/fileUploader/vendor/blueimp-load-image/js/load-image-exif',
  22. 'jquery/fileUploader/vendor/blueimp-load-image/js/load-image-orientation',
  23. 'jquery/fileUploader/vendor/blueimp-canvas-to-blob/js/canvas-to-blob',
  24. 'jquery/fileUploader/jquery.fileupload-process'
  25. ], factory);
  26. } else if (typeof exports === 'object') {
  27. // Node/CommonJS:
  28. factory(
  29. require('jquery'),
  30. require('jquery/fileUploader/vendor/blueimp-load-image/js/load-image'),
  31. require('jquery/fileUploader/vendor/blueimp-load-image/js/load-image-meta'),
  32. require('jquery/fileUploader/vendor/blueimp-load-image/js/load-image-scale'),
  33. require('jquery/fileUploader/vendor/blueimp-load-image/js/load-image-exif'),
  34. require('jquery/fileUploader/vendor/blueimp-load-image/js/load-image-orientation'),
  35. require('jquery/fileUploader/vendor/blueimp-canvas-to-blob/js/canvas-to-blob'),
  36. require('jquery/fileUploader/jquery.fileupload-process')
  37. );
  38. } else {
  39. // Browser globals:
  40. factory(window.jQuery, window.loadImage);
  41. }
  42. })(function ($, loadImage) {
  43. 'use strict';
  44. // Prepend to the default processQueue:
  45. $.blueimp.fileupload.prototype.options.processQueue.unshift(
  46. {
  47. action: 'loadImageMetaData',
  48. maxMetaDataSize: '@',
  49. disableImageHead: '@',
  50. disableMetaDataParsers: '@',
  51. disableExif: '@',
  52. disableExifOffsets: '@',
  53. includeExifTags: '@',
  54. excludeExifTags: '@',
  55. disableIptc: '@',
  56. disableIptcOffsets: '@',
  57. includeIptcTags: '@',
  58. excludeIptcTags: '@',
  59. disabled: '@disableImageMetaDataLoad'
  60. },
  61. {
  62. action: 'loadImage',
  63. // Use the action as prefix for the "@" options:
  64. prefix: true,
  65. fileTypes: '@',
  66. maxFileSize: '@',
  67. noRevoke: '@',
  68. disabled: '@disableImageLoad'
  69. },
  70. {
  71. action: 'resizeImage',
  72. // Use "image" as prefix for the "@" options:
  73. prefix: 'image',
  74. maxWidth: '@',
  75. maxHeight: '@',
  76. minWidth: '@',
  77. minHeight: '@',
  78. crop: '@',
  79. orientation: '@',
  80. forceResize: '@',
  81. disabled: '@disableImageResize'
  82. },
  83. {
  84. action: 'saveImage',
  85. quality: '@imageQuality',
  86. type: '@imageType',
  87. disabled: '@disableImageResize'
  88. },
  89. {
  90. action: 'saveImageMetaData',
  91. disabled: '@disableImageMetaDataSave'
  92. },
  93. {
  94. action: 'resizeImage',
  95. // Use "preview" as prefix for the "@" options:
  96. prefix: 'preview',
  97. maxWidth: '@',
  98. maxHeight: '@',
  99. minWidth: '@',
  100. minHeight: '@',
  101. crop: '@',
  102. orientation: '@',
  103. thumbnail: '@',
  104. canvas: '@',
  105. disabled: '@disableImagePreview'
  106. },
  107. {
  108. action: 'setImage',
  109. name: '@imagePreviewName',
  110. disabled: '@disableImagePreview'
  111. },
  112. {
  113. action: 'deleteImageReferences',
  114. disabled: '@disableImageReferencesDeletion'
  115. }
  116. );
  117. // The File Upload Resize plugin extends the fileupload widget
  118. // with image resize functionality:
  119. $.widget('blueimp.fileupload', $.blueimp.fileupload, {
  120. options: {
  121. // The regular expression for the types of images to load:
  122. // matched against the file type:
  123. loadImageFileTypes: /^image\/(gif|jpeg|png|svg\+xml)$/,
  124. // The maximum file size of images to load:
  125. loadImageMaxFileSize: 10000000, // 10MB
  126. // The maximum width of resized images:
  127. imageMaxWidth: 1920,
  128. // The maximum height of resized images:
  129. imageMaxHeight: 1080,
  130. // Defines the image orientation (1-8) or takes the orientation
  131. // value from Exif data if set to true:
  132. imageOrientation: true,
  133. // Define if resized images should be cropped or only scaled:
  134. imageCrop: false,
  135. // Disable the resize image functionality by default:
  136. disableImageResize: true,
  137. // The maximum width of the preview images:
  138. previewMaxWidth: 80,
  139. // The maximum height of the preview images:
  140. previewMaxHeight: 80,
  141. // Defines the preview orientation (1-8) or takes the orientation
  142. // value from Exif data if set to true:
  143. previewOrientation: true,
  144. // Create the preview using the Exif data thumbnail:
  145. previewThumbnail: true,
  146. // Define if preview images should be cropped or only scaled:
  147. previewCrop: false,
  148. // Define if preview images should be resized as canvas elements:
  149. previewCanvas: true
  150. },
  151. processActions: {
  152. // Loads the image given via data.files and data.index
  153. // as img element, if the browser supports the File API.
  154. // Accepts the options fileTypes (regular expression)
  155. // and maxFileSize (integer) to limit the files to load:
  156. loadImage: function (data, options) {
  157. if (options.disabled) {
  158. return data;
  159. }
  160. var that = this,
  161. file = data.files[data.index],
  162. // eslint-disable-next-line new-cap
  163. dfd = $.Deferred();
  164. if (
  165. ($.type(options.maxFileSize) === 'number' &&
  166. file.size > options.maxFileSize) ||
  167. (options.fileTypes && !options.fileTypes.test(file.type)) ||
  168. !loadImage(
  169. file,
  170. function (img) {
  171. if (img.src) {
  172. data.img = img;
  173. }
  174. dfd.resolveWith(that, [data]);
  175. },
  176. options
  177. )
  178. ) {
  179. return data;
  180. }
  181. return dfd.promise();
  182. },
  183. // Resizes the image given as data.canvas or data.img
  184. // and updates data.canvas or data.img with the resized image.
  185. // Also stores the resized image as preview property.
  186. // Accepts the options maxWidth, maxHeight, minWidth,
  187. // minHeight, canvas and crop:
  188. resizeImage: function (data, options) {
  189. if (options.disabled || !(data.canvas || data.img)) {
  190. return data;
  191. }
  192. // eslint-disable-next-line no-param-reassign
  193. options = $.extend({ canvas: true }, options);
  194. var that = this,
  195. // eslint-disable-next-line new-cap
  196. dfd = $.Deferred(),
  197. img = (options.canvas && data.canvas) || data.img,
  198. resolve = function (newImg) {
  199. if (
  200. newImg &&
  201. (newImg.width !== img.width ||
  202. newImg.height !== img.height ||
  203. options.forceResize)
  204. ) {
  205. data[newImg.getContext ? 'canvas' : 'img'] = newImg;
  206. }
  207. data.preview = newImg;
  208. dfd.resolveWith(that, [data]);
  209. },
  210. thumbnail,
  211. thumbnailBlob;
  212. if (data.exif && options.thumbnail) {
  213. thumbnail = data.exif.get('Thumbnail');
  214. thumbnailBlob = thumbnail && thumbnail.get('Blob');
  215. if (thumbnailBlob) {
  216. options.orientation = data.exif.get('Orientation');
  217. loadImage(thumbnailBlob, resolve, options);
  218. return dfd.promise();
  219. }
  220. }
  221. if (data.orientation) {
  222. // Prevent orienting the same image twice:
  223. delete options.orientation;
  224. } else {
  225. data.orientation = options.orientation || loadImage.orientation;
  226. }
  227. if (img) {
  228. resolve(loadImage.scale(img, options, data));
  229. return dfd.promise();
  230. }
  231. return data;
  232. },
  233. // Saves the processed image given as data.canvas
  234. // inplace at data.index of data.files:
  235. saveImage: function (data, options) {
  236. if (!data.canvas || options.disabled) {
  237. return data;
  238. }
  239. var that = this,
  240. file = data.files[data.index],
  241. // eslint-disable-next-line new-cap
  242. dfd = $.Deferred();
  243. if (data.canvas.toBlob) {
  244. data.canvas.toBlob(
  245. function (blob) {
  246. if (!blob.name) {
  247. if (file.type === blob.type) {
  248. blob.name = file.name;
  249. } else if (file.name) {
  250. blob.name = file.name.replace(
  251. /\.\w+$/,
  252. '.' + blob.type.substr(6)
  253. );
  254. }
  255. }
  256. // Don't restore invalid meta data:
  257. if (file.type !== blob.type) {
  258. delete data.imageHead;
  259. }
  260. // Store the created blob at the position
  261. // of the original file in the files list:
  262. data.files[data.index] = blob;
  263. dfd.resolveWith(that, [data]);
  264. },
  265. options.type || file.type,
  266. options.quality
  267. );
  268. } else {
  269. return data;
  270. }
  271. return dfd.promise();
  272. },
  273. loadImageMetaData: function (data, options) {
  274. if (options.disabled) {
  275. return data;
  276. }
  277. var that = this,
  278. // eslint-disable-next-line new-cap
  279. dfd = $.Deferred();
  280. loadImage.parseMetaData(
  281. data.files[data.index],
  282. function (result) {
  283. $.extend(data, result);
  284. dfd.resolveWith(that, [data]);
  285. },
  286. options
  287. );
  288. return dfd.promise();
  289. },
  290. saveImageMetaData: function (data, options) {
  291. if (
  292. !(
  293. data.imageHead &&
  294. data.canvas &&
  295. data.canvas.toBlob &&
  296. !options.disabled
  297. )
  298. ) {
  299. return data;
  300. }
  301. var that = this,
  302. file = data.files[data.index],
  303. // eslint-disable-next-line new-cap
  304. dfd = $.Deferred();
  305. if (data.orientation === true && data.exifOffsets) {
  306. // Reset Exif Orientation data:
  307. loadImage.writeExifData(data.imageHead, data, 'Orientation', 1);
  308. }
  309. loadImage.replaceHead(file, data.imageHead, function (blob) {
  310. blob.name = file.name;
  311. data.files[data.index] = blob;
  312. dfd.resolveWith(that, [data]);
  313. });
  314. return dfd.promise();
  315. },
  316. // Sets the resized version of the image as a property of the
  317. // file object, must be called after "saveImage":
  318. setImage: function (data, options) {
  319. if (data.preview && !options.disabled) {
  320. data.files[data.index][options.name || 'preview'] = data.preview;
  321. }
  322. return data;
  323. },
  324. deleteImageReferences: function (data, options) {
  325. if (!options.disabled) {
  326. delete data.img;
  327. delete data.canvas;
  328. delete data.preview;
  329. delete data.imageHead;
  330. }
  331. return data;
  332. }
  333. }
  334. });
  335. });