compress.js 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160
  1. /**
  2. * 图片压缩
  3. * @param {String} imgUrl 需要压缩的图片路径
  4. * @param {Object} self 必传,当前组件对象
  5. * @param {Object} options 压缩参数
  6. * width: 压缩到多宽,默认图片宽度(待优化,传入宽度,应计算高度)
  7. * height: 压缩到多高,默认图片高度
  8. * pixels: 压缩图片的最大分辨率,默认二百万
  9. * quality: 压缩质量,默认0.8
  10. * type: 获取的base64类型,默认jpg
  11. * base64: 是否返回base64,默认true(非H5有效)
  12. * @return {Promise}
  13. * reject
  14. * code
  15. * -1: 获取图片信息错误
  16. * -2: 极大可能创建图片对象出错(h5会出现,出现概率无限接近0)
  17. * -3: canvas转图片错误(小程序会出现)
  18. * -4: 图片转base64错误(小程序会出现)
  19. */
  20. // 图片分辨率压缩
  21. const calcImageSize = (res, pixels) => {
  22. let imgW, imgH
  23. imgW = res.width
  24. imgH = res.height
  25. let ratio
  26. if((ratio = imgW * imgH / pixels) > 1) {
  27. ratio = Math.sqrt(ratio)
  28. imgW = parseInt(imgW / ratio)
  29. imgH = parseInt(imgH / ratio)
  30. } else {
  31. ratio = 1
  32. }
  33. return { imgW, imgH }
  34. }
  35. const urlTobase64 = (url, type) => {
  36. return new Promise((resolve, reject) => {
  37. uni.getFileSystemManager().readFile({
  38. filePath: url,
  39. encoding: 'base64',
  40. success: res => {
  41. let base64 = res.data
  42. base64 = `data:image/${type};base64,${base64}`
  43. resolve(base64)
  44. }
  45. })
  46. })
  47. }
  48. const compress = (imgUrl, slef, options={}) => {
  49. /*************** 参数默认值 ***************/
  50. const MAX_PIXELS = 2000000 // 最大分辨率,宽 * 高 的值
  51. const MAX_QUALITY = 0.8 // 压缩质量
  52. const IMG_TYPE = 'jpg'
  53. const CANVAS_ID = 'compress_canvas'
  54. const BASE_64 = false
  55. return new Promise((resolve, reject) => {
  56. uni.getImageInfo({
  57. src: imgUrl,
  58. success: res => {
  59. let pixels = options.pixels || MAX_PIXELS
  60. let quality = options.quality || MAX_QUALITY
  61. let type = options.type || IMG_TYPE
  62. let canvasId = options.canvasId || CANVAS_ID
  63. let isBase64 = options.base64 || BASE_64
  64. let { imgW, imgH } = calcImageSize(res, pixels)
  65. let w = options.width || imgW
  66. let h = options.height || imgH
  67. // #ifdef H5
  68. type = type == 'jpg' ? 'jpeg' : type,
  69. // #endif
  70. // #ifndef H5
  71. type = type == 'png' ? 'png' : 'jpg',
  72. // #endif
  73. console.log(`%c 宽: ${w} %c 高: ${h} %c 分辨率: ${w * h} %c 质量: ${quality} %c 类型: ${type}`, 'color:#f00', 'background-color:#f60;color:#fff', 'color:#F00', 'background-color:#f60;color:#fff', 'color:#F00')
  74. // #ifdef H5
  75. let img = new Image()
  76. img.src = res.path
  77. img.onload = () => {
  78. const canvas = document.createElement('canvas')
  79. const ctx = canvas.getContext('2d')
  80. canvas.width = w
  81. canvas.height = h
  82. let drawW = w, drawH = h
  83. ctx.drawImage(img, 0, 0, drawW, drawH)
  84. let base64 = canvas.toDataURL(`image/${type}`, quality)
  85. resolve(base64)
  86. }
  87. // #endif
  88. // 非h5
  89. // #ifndef H5
  90. slef.height = h
  91. slef.width = w
  92. slef.$nextTick(function() {
  93. let canvas = null
  94. if(!canvas) {
  95. canvas = uni.createCanvasContext(canvasId, slef)
  96. }
  97. canvas.drawImage(res.path, 0, 0, w, h)
  98. canvas.draw()
  99. setTimeout(() => {
  100. uni.canvasToTempFilePath({
  101. canvasId: canvasId,
  102. x: 0,
  103. y: 0,
  104. width: w,
  105. height: h,
  106. destWidth: w,
  107. destHeight: h,
  108. fileType: type,
  109. quality: quality,
  110. success: file => {
  111. if(isBase64) {
  112. urlTobase64(file.tempFilePath, type)
  113. .then(res => {
  114. canvas = null
  115. resolve(res)
  116. })
  117. .catch(e => {
  118. reject({
  119. code: -4,
  120. msg: '图片转base64错误',
  121. data: e
  122. })
  123. })
  124. } else {
  125. resolve(file.tempFilePath)
  126. }
  127. },
  128. fail: e => {
  129. reject({
  130. code: -3,
  131. msg: 'canvas转图片错误',
  132. data: e
  133. })
  134. }
  135. }, slef)
  136. }, 500)
  137. })
  138. // #endif
  139. }
  140. })
  141. })
  142. }
  143. export default compress