test.js 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510
  1. /*
  2. * JavaScript Load Image Test
  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. * http://www.opensource.org/licenses/MIT
  10. */
  11. /*global window, describe, it, Blob */
  12. ;(function (expect, loadImage) {
  13. 'use strict'
  14. var canCreateBlob = !!window.dataURLtoBlob
  15. // 80x60px GIF image (color black, base64 data):
  16. var b64DataGIF = 'R0lGODdhUAA8AIABAAAAAP///ywAAAAAUAA8AAACS4SPqcvtD6' +
  17. 'OctNqLs968+w+G4kiW5omm6sq27gvH8kzX9o3n+s73/g8MCofE' +
  18. 'ovGITCqXzKbzCY1Kp9Sq9YrNarfcrvcLDovH5PKsAAA7'
  19. var imageUrlGIF = 'data:image/gif;base64,' + b64DataGIF
  20. var blobGIF = canCreateBlob && window.dataURLtoBlob(imageUrlGIF)
  21. // 1x2px JPEG (color white, with the Exif orientation flag set to 6):
  22. var b64DataJPEG = '/9j/4AAQSkZJRgABAQEAYABgAAD/4QAiRXhpZgAASUkqAAgAAA' +
  23. 'ABABIBAwABAAAABgASAAAAAAD/2wBDAAEBAQEBAQEBAQEBAQEB' +
  24. 'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ' +
  25. 'EBAQEBAQEBAQEBAQH/2wBDAQEBAQEBAQEBAQEBAQEBAQEBAQEB' +
  26. 'AQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQEBAQ' +
  27. 'EBAQEBAQH/wAARCAABAAIDASIAAhEBAxEB/8QAHwAAAQUBAQEB' +
  28. 'AQEAAAAAAAAAAAECAwQFBgcICQoL/8QAtRAAAgEDAwIEAwUFBA' +
  29. 'QAAAF9AQIDAAQRBRIhMUEGE1FhByJxFDKBkaEII0KxwRVS0fAk' +
  30. 'M2JyggkKFhcYGRolJicoKSo0NTY3ODk6Q0RFRkdISUpTVFVWV1' +
  31. 'hZWmNkZWZnaGlqc3R1dnd4eXqDhIWGh4iJipKTlJWWl5iZmqKj' +
  32. 'pKWmp6ipqrKztLW2t7i5usLDxMXGx8jJytLT1NXW19jZ2uHi4+' +
  33. 'Tl5ufo6erx8vP09fb3+Pn6/8QAHwEAAwEBAQEBAQEBAQAAAAAA' +
  34. 'AAECAwQFBgcICQoL/8QAtREAAgECBAQDBAcFBAQAAQJ3AAECAx' +
  35. 'EEBSExBhJBUQdhcRMiMoEIFEKRobHBCSMzUvAVYnLRChYkNOEl' +
  36. '8RcYGRomJygpKjU2Nzg5OkNERUZHSElKU1RVVldYWVpjZGVmZ2' +
  37. 'hpanN0dXZ3eHl6goOEhYaHiImKkpOUlZaXmJmaoqOkpaanqKmq' +
  38. 'srO0tba3uLm6wsPExcbHyMnK0tPU1dbX2Nna4uPk5ebn6Onq8v' +
  39. 'P09fb3+Pn6/9oADAMBAAIRAxEAPwD+/iiiigD/2Q=='
  40. var imageUrlJPEG = 'data:image/jpeg;base64,' + b64DataJPEG
  41. var blobJPEG = canCreateBlob && window.dataURLtoBlob(imageUrlJPEG)
  42. function createBlob (data, type) {
  43. try {
  44. return new Blob([data], {type: type})
  45. } catch (e) {
  46. var BlobBuilder = window.BlobBuilder || window.WebKitBlobBuilder ||
  47. window.MozBlobBuilder || window.MSBlobBuilder
  48. var builder = new BlobBuilder()
  49. builder.append(data.buffer || data)
  50. return builder.getBlob(type)
  51. }
  52. }
  53. describe('Loading', function () {
  54. it('Return the img element or FileReader object to allow aborting the image load', function () {
  55. var img = loadImage(blobGIF, function () {
  56. return
  57. })
  58. expect(img).to.be.an(Object)
  59. expect(img.onload).to.be.a('function')
  60. expect(img.onerror).to.be.a('function')
  61. })
  62. it('Load image url', function (done) {
  63. expect(loadImage(imageUrlGIF, function (img) {
  64. expect(img.width).to.be(80)
  65. expect(img.height).to.be(60)
  66. done()
  67. })).to.be.ok()
  68. })
  69. it('Load image blob', function (done) {
  70. expect(loadImage(blobGIF, function (img) {
  71. expect(img.width).to.be(80)
  72. expect(img.height).to.be(60)
  73. done()
  74. })).to.be.ok()
  75. })
  76. it('Return image loading error to callback', function (done) {
  77. expect(loadImage('404', function (img) {
  78. expect(img).to.be.a(window.Event)
  79. expect(img.type).to.be('error')
  80. done()
  81. })).to.be.ok()
  82. })
  83. it('Keep object URL if noRevoke is true', function (done) {
  84. expect(loadImage(blobGIF, function (img) {
  85. loadImage(img.src, function (img2) {
  86. expect(img.width).to.be(img2.width)
  87. expect(img.height).to.be(img2.height)
  88. done()
  89. })
  90. }, {noRevoke: true})).to.be.ok()
  91. })
  92. it('Discard object URL if noRevoke is undefined or false', function (done) {
  93. expect(loadImage(blobGIF, function (img) {
  94. loadImage(img.src, function (img2) {
  95. if (!window.callPhantom) {
  96. // revokeObjectUrl doesn't seem to have an effect in PhantomJS
  97. expect(img2).to.be.a(window.Event)
  98. expect(img2.type).to.be('error')
  99. }
  100. done()
  101. })
  102. })).to.be.ok()
  103. })
  104. })
  105. describe('Scaling', function () {
  106. describe('max/min', function () {
  107. it('Scale to maxWidth', function (done) {
  108. expect(loadImage(blobGIF, function (img) {
  109. expect(img.width).to.be(40)
  110. expect(img.height).to.be(30)
  111. done()
  112. }, {maxWidth: 40})).to.be.ok()
  113. })
  114. it('Scale to maxHeight', function (done) {
  115. expect(loadImage(blobGIF, function (img) {
  116. expect(img.width).to.be(20)
  117. expect(img.height).to.be(15)
  118. done()
  119. }, {maxHeight: 15})).to.be.ok()
  120. })
  121. it('Scale to minWidth', function (done) {
  122. expect(loadImage(blobGIF, function (img) {
  123. expect(img.width).to.be(160)
  124. expect(img.height).to.be(120)
  125. done()
  126. }, {minWidth: 160})).to.be.ok()
  127. })
  128. it('Scale to minHeight', function (done) {
  129. expect(loadImage(blobGIF, function (img) {
  130. expect(img.width).to.be(320)
  131. expect(img.height).to.be(240)
  132. done()
  133. }, {minHeight: 240})).to.be.ok()
  134. })
  135. it('Scale to minWidth but respect maxWidth', function (done) {
  136. expect(loadImage(blobGIF, function (img) {
  137. expect(img.width).to.be(160)
  138. expect(img.height).to.be(120)
  139. done()
  140. }, {minWidth: 240, maxWidth: 160})).to.be.ok()
  141. })
  142. it('Scale to minHeight but respect maxHeight', function (done) {
  143. expect(loadImage(blobGIF, function (img) {
  144. expect(img.width).to.be(160)
  145. expect(img.height).to.be(120)
  146. done()
  147. }, {minHeight: 180, maxHeight: 120})).to.be.ok()
  148. })
  149. it('Scale to minWidth but respect maxHeight', function (done) {
  150. expect(loadImage(blobGIF, function (img) {
  151. expect(img.width).to.be(160)
  152. expect(img.height).to.be(120)
  153. done()
  154. }, {minWidth: 240, maxHeight: 120})).to.be.ok()
  155. })
  156. it('Scale to minHeight but respect maxWidth', function (done) {
  157. expect(loadImage(blobGIF, function (img) {
  158. expect(img.width).to.be(160)
  159. expect(img.height).to.be(120)
  160. done()
  161. }, {minHeight: 180, maxWidth: 160})).to.be.ok()
  162. })
  163. it('Scale up with the given pixelRatio', function (done) {
  164. expect(loadImage(blobGIF, function (img) {
  165. expect(img.width).to.be(320)
  166. expect(img.height).to.be(240)
  167. expect(img.style.width).to.be('160px')
  168. expect(img.style.height).to.be('120px')
  169. done()
  170. }, {minWidth: 160, canvas: true, pixelRatio: 2})).to.be.ok()
  171. })
  172. it('Scale down with the given pixelRatio', function (done) {
  173. expect(loadImage(blobGIF, function (img) {
  174. expect(img.width).to.be(80)
  175. expect(img.height).to.be(60)
  176. expect(img.style.width).to.be('40px')
  177. expect(img.style.height).to.be('30px')
  178. done()
  179. }, {maxWidth: 40, canvas: true, pixelRatio: 2})).to.be.ok()
  180. })
  181. it('Scale down with the given downsamplingRatio', function (done) {
  182. expect(loadImage(blobGIF, function (img) {
  183. expect(img.width).to.be(20)
  184. expect(img.height).to.be(15)
  185. done()
  186. }, {maxWidth: 20, canvas: true, downsamplingRatio: 0.5})).to.be.ok()
  187. })
  188. it('Ignore max settings if image dimensions are smaller', function (done) {
  189. expect(loadImage(blobGIF, function (img) {
  190. expect(img.width).to.be(80)
  191. expect(img.height).to.be(60)
  192. done()
  193. }, {maxWidth: 160, maxHeight: 120})).to.be.ok()
  194. })
  195. it('Ignore min settings if image dimensions are larger', function (done) {
  196. expect(loadImage(blobGIF, function (img) {
  197. expect(img.width).to.be(80)
  198. expect(img.height).to.be(60)
  199. done()
  200. }, {minWidth: 40, minHeight: 30})).to.be.ok()
  201. })
  202. })
  203. describe('contain', function () {
  204. it('Scale up to contain image in max dimensions', function (done) {
  205. expect(loadImage(blobGIF, function (img) {
  206. expect(img.width).to.be(160)
  207. expect(img.height).to.be(120)
  208. done()
  209. }, {maxWidth: 160, maxHeight: 160, contain: true})).to.be.ok()
  210. })
  211. it('Scale down to contain image in max dimensions', function (done) {
  212. expect(loadImage(blobGIF, function (img) {
  213. expect(img.width).to.be(40)
  214. expect(img.height).to.be(30)
  215. done()
  216. }, {maxWidth: 40, maxHeight: 40, contain: true})).to.be.ok()
  217. })
  218. })
  219. describe('cover', function () {
  220. it('Scale up to cover max dimensions with image dimensions', function (done) {
  221. expect(loadImage(blobGIF, function (img) {
  222. expect(img.width).to.be(160)
  223. expect(img.height).to.be(120)
  224. done()
  225. }, {maxWidth: 120, maxHeight: 120, cover: true})).to.be.ok()
  226. })
  227. it('Scale down to cover max dimensions with image dimensions', function (done) {
  228. expect(loadImage(blobGIF, function (img) {
  229. expect(img.width).to.be(40)
  230. expect(img.height).to.be(30)
  231. done()
  232. }, {maxWidth: 30, maxHeight: 30, cover: true})).to.be.ok()
  233. })
  234. })
  235. })
  236. describe('Cropping', function () {
  237. it('Crop to same values for maxWidth and maxHeight', function (done) {
  238. expect(loadImage(blobGIF, function (img) {
  239. expect(img.width).to.be(40)
  240. expect(img.height).to.be(40)
  241. done()
  242. }, {maxWidth: 40, maxHeight: 40, crop: true})).to.be.ok()
  243. })
  244. it('Crop to different values for maxWidth and maxHeight', function (done) {
  245. expect(loadImage(blobGIF, function (img) {
  246. expect(img.width).to.be(40)
  247. expect(img.height).to.be(60)
  248. done()
  249. }, {maxWidth: 40, maxHeight: 60, crop: true})).to.be.ok()
  250. })
  251. it('Crop using the given sourceWidth and sourceHeight dimensions', function (done) {
  252. expect(loadImage(blobGIF, function (img) {
  253. expect(img.width).to.be(40)
  254. expect(img.height).to.be(40)
  255. done()
  256. }, {sourceWidth: 40, sourceHeight: 40, crop: true})).to.be.ok()
  257. })
  258. it('Crop using the given left and top coordinates', function (done) {
  259. expect(loadImage(blobGIF, function (img) {
  260. expect(img.width).to.be(40)
  261. expect(img.height).to.be(20)
  262. done()
  263. }, {left: 40, top: 40, crop: true})).to.be.ok()
  264. })
  265. it('Crop using the given right and bottom coordinates', function (done) {
  266. expect(loadImage(blobGIF, function (img) {
  267. expect(img.width).to.be(40)
  268. expect(img.height).to.be(20)
  269. done()
  270. }, {right: 40, bottom: 40, crop: true})).to.be.ok()
  271. })
  272. it('Crop using the given 2:1 aspectRatio', function (done) {
  273. expect(loadImage(blobGIF, function (img) {
  274. expect(img.width).to.be(80)
  275. expect(img.height).to.be(40)
  276. done()
  277. }, {aspectRatio: 2})).to.be.ok()
  278. })
  279. it('Crop using the given 2:3 aspectRatio', function (done) {
  280. expect(loadImage(blobGIF, function (img) {
  281. expect(img.width).to.be(40)
  282. expect(img.height).to.be(60)
  283. done()
  284. }, {aspectRatio: 2 / 3})).to.be.ok()
  285. })
  286. it('Crop using maxWidth/maxHeight with the given pixelRatio', function (done) {
  287. expect(loadImage(blobGIF, function (img) {
  288. expect(img.width).to.be(80)
  289. expect(img.height).to.be(80)
  290. expect(img.style.width).to.be('40px')
  291. expect(img.style.height).to.be('40px')
  292. done()
  293. }, {maxWidth: 40, maxHeight: 40, crop: true, pixelRatio: 2})).to.be.ok()
  294. })
  295. it('Crop using sourceWidth/sourceHeight with the given pixelRatio', function (done) {
  296. expect(loadImage(blobGIF, function (img) {
  297. expect(img.width).to.be(80)
  298. expect(img.height).to.be(80)
  299. expect(img.style.width).to.be('40px')
  300. expect(img.style.height).to.be('40px')
  301. done()
  302. }, {sourceWidth: 40, sourceHeight: 40, crop: true, pixelRatio: 2})).to.be.ok()
  303. })
  304. })
  305. describe('Orientation', function () {
  306. it('Should keep the orientation', function (done) {
  307. expect(loadImage(blobGIF, function (img) {
  308. expect(img.width).to.be(80)
  309. expect(img.height).to.be(60)
  310. done()
  311. }, {orientation: 1})).to.be.ok()
  312. })
  313. it('Should rotate left', function (done) {
  314. expect(loadImage(blobGIF, function (img) {
  315. expect(img.width).to.be(60)
  316. expect(img.height).to.be(80)
  317. done()
  318. }, {orientation: 8})).to.be.ok()
  319. })
  320. it('Should rotate right', function (done) {
  321. expect(loadImage(blobGIF, function (img) {
  322. expect(img.width).to.be(60)
  323. expect(img.height).to.be(80)
  324. done()
  325. }, {orientation: 6})).to.be.ok()
  326. })
  327. it('Should adjust constraints to new coordinates', function (done) {
  328. expect(loadImage(blobGIF, function (img) {
  329. expect(img.width).to.be(60)
  330. expect(img.height).to.be(80)
  331. done()
  332. }, {orientation: 6, maxWidth: 60, maxHeight: 80})).to.be.ok()
  333. })
  334. it('Should adjust left and top to new coordinates', function (done) {
  335. expect(loadImage(blobGIF, function (img) {
  336. expect(img.width).to.be(30)
  337. expect(img.height).to.be(60)
  338. done()
  339. }, {orientation: 5, left: 30, top: 20})).to.be.ok()
  340. })
  341. it('Should adjust right and bottom to new coordinates', function (done) {
  342. expect(loadImage(blobGIF, function (img) {
  343. expect(img.width).to.be(30)
  344. expect(img.height).to.be(60)
  345. done()
  346. }, {orientation: 5, right: 30, bottom: 20})).to.be.ok()
  347. })
  348. it('Should adjust left and bottom to new coordinates', function (done) {
  349. expect(loadImage(blobGIF, function (img) {
  350. expect(img.width).to.be(30)
  351. expect(img.height).to.be(60)
  352. done()
  353. }, {orientation: 7, left: 30, bottom: 20})).to.be.ok()
  354. })
  355. it('Should adjust right and top to new coordinates', function (done) {
  356. expect(loadImage(blobGIF, function (img) {
  357. expect(img.width).to.be(30)
  358. expect(img.height).to.be(60)
  359. done()
  360. }, {orientation: 7, right: 30, top: 20})).to.be.ok()
  361. })
  362. it('Should rotate left with the given pixelRatio', function (done) {
  363. expect(loadImage(blobGIF, function (img) {
  364. expect(img.width).to.be(120)
  365. expect(img.height).to.be(160)
  366. expect(img.style.width).to.be('60px')
  367. expect(img.style.height).to.be('80px')
  368. done()
  369. }, {orientation: 8, pixelRatio: 2})).to.be.ok()
  370. })
  371. it('Should rotate right with the given pixelRatio', function (done) {
  372. expect(loadImage(blobGIF, function (img) {
  373. expect(img.width).to.be(120)
  374. expect(img.height).to.be(160)
  375. expect(img.style.width).to.be('60px')
  376. expect(img.style.height).to.be('80px')
  377. done()
  378. }, {orientation: 6, pixelRatio: 2})).to.be.ok()
  379. })
  380. it('Should ignore too small orientation value', function (done) {
  381. expect(loadImage(blobGIF, function (img) {
  382. expect(img.width).to.be(80)
  383. expect(img.height).to.be(60)
  384. done()
  385. }, {orientation: -1})).to.be.ok()
  386. })
  387. it('Should ignore too large orientation value', function (done) {
  388. expect(loadImage(blobGIF, function (img) {
  389. expect(img.width).to.be(80)
  390. expect(img.height).to.be(60)
  391. done()
  392. }, {orientation: 9})).to.be.ok()
  393. })
  394. })
  395. describe('Canvas', function () {
  396. it('Return img element to callback if canvas is not true', function (done) {
  397. expect(loadImage(blobGIF, function (img) {
  398. expect(img.getContext).to.not.be.ok()
  399. expect(img.nodeName.toLowerCase()).to.be('img')
  400. done()
  401. })).to.be.ok()
  402. })
  403. it('Return canvas element to callback if canvas is true', function (done) {
  404. expect(loadImage(blobGIF, function (img) {
  405. expect(img.getContext).to.be.ok()
  406. expect(img.nodeName.toLowerCase()).to.be('canvas')
  407. done()
  408. }, {canvas: true})).to.be.ok()
  409. })
  410. it('Return scaled canvas element to callback', function (done) {
  411. expect(loadImage(blobGIF, function (img) {
  412. expect(img.getContext).to.be.ok()
  413. expect(img.nodeName.toLowerCase()).to.be('canvas')
  414. expect(img.width).to.be(40)
  415. expect(img.height).to.be(30)
  416. done()
  417. }, {canvas: true, maxWidth: 40})).to.be.ok()
  418. })
  419. it('Accept a canvas element as parameter for loadImage.scale', function (done) {
  420. expect(loadImage(blobGIF, function (img) {
  421. img = loadImage.scale(img, {
  422. maxWidth: 40
  423. })
  424. expect(img.getContext).to.be.ok()
  425. expect(img.nodeName.toLowerCase()).to.be('canvas')
  426. expect(img.width).to.be(40)
  427. expect(img.height).to.be(30)
  428. done()
  429. }, {canvas: true})).to.be.ok()
  430. })
  431. })
  432. describe('Metadata', function () {
  433. it('Should parse Exif information', function (done) {
  434. loadImage.parseMetaData(blobJPEG, function (data) {
  435. expect(data.exif).to.be.ok()
  436. expect(data.exif.get('Orientation')).to.be(6)
  437. done()
  438. })
  439. })
  440. it('Should parse the complete image head', function (done) {
  441. loadImage.parseMetaData(blobJPEG, function (data) {
  442. expect(data.imageHead).to.be.ok()
  443. loadImage.parseMetaData(
  444. createBlob(data.imageHead, 'image/jpeg'),
  445. function (data) {
  446. expect(data.exif).to.be.ok()
  447. expect(data.exif.get('Orientation')).to.be(6)
  448. done()
  449. }
  450. )
  451. })
  452. })
  453. })
  454. }(
  455. this.expect,
  456. this.loadImage
  457. ))