compressPhoto.js 4.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. //通过canvas将图片压缩至指定大小
  2. //判断图片大小是否满足需求,limitSize的单位是kb
  3. function imageSizeIsLessLimitSize(imagePath,limitSize,lessCallback,moreCallback){
  4. console.log('------imagePath,limitSize,lessCallback,moreCallback', imagePath,limitSize,lessCallback,moreCallback)
  5. //获取文件信息
  6. wx.getFileSystemManager().getFileInfo({
  7. filePath: imagePath,
  8. success:(res)=>{
  9. // console.log("压缩前图片大小",res, res.size/1024,'kb');
  10. if(res.size > 1024*limitSize){
  11. moreCallback()
  12. } else {
  13. lessCallback()
  14. }
  15. }
  16. })
  17. }
  18. //将图片画在画布上并获取画好之后的图片的路径
  19. function getCanvasImage(canvasId,imagePath,imageW,imageH,getImgSuccess){
  20. //创建画布内容
  21. const ctx = wx.createCanvasContext(canvasId)
  22. //图片画上去,imageW和imageH是画上去的尺寸,图像和画布间隔都是0
  23. ctx.drawImage(imagePath, 0, 0, imageW, imageH);
  24. //这里一定要加定时器,给足够的时间去画(所以每次递归最少要耗时200ms,多次递归很耗时!)
  25. ctx.draw(false, setTimeout(() => {
  26. //把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径
  27. wx.canvasToTempFilePath({
  28. canvasId: canvasId,
  29. x: 0,
  30. y: 0,
  31. width: imageW,
  32. height: imageH,
  33. quality: 1, // 取0-1,1最高质量
  34. fileType: 'jpg',
  35. success:(res)=>{
  36. //将取出的图片路径通过回调函数返回
  37. getImgSuccess(res.tempFilePath);
  38. }
  39. })
  40. },200));
  41. }
  42. //主函数,默认限制大小2048kb即2mb,drawWidth是绘画区域的大小
  43. //初始值传入为画布自身的边长(我们这是一个正方形的画布)
  44. function getLessLimitSizeImage(canvasId, imagePath, limitSize=1024, drawWidth, callback) {
  45. //判断图片尺寸是否满足要求
  46. imageSizeIsLessLimitSize(imagePath,limitSize,
  47. (lessRes)=>{
  48. //满足要求走callback,将压缩后的文件路径返回
  49. console.log('满足要求走callback:', imagePath)
  50. callback(imagePath);
  51. },
  52. (moreRes)=>{
  53. //不满足要求需要压缩的时候
  54. wx.getImageInfo({
  55. src: imagePath,
  56. success:(imageInfo)=>{
  57. let maxSide = Math.max(imageInfo.width,imageInfo.height);
  58. let windowW = drawWidth
  59. let scale=1;
  60. /*
  61. 这里的目的是当绘画区域缩小的比图片自身尺寸还要小的时候
  62. 取图片长宽的最大值,然后和当前绘画区域计算出需要放缩的比例
  63. 然后再画经过放缩后的尺寸,保证画出的一定是一个完整的图片。由于每次递归绘画区域都会缩小,
  64. 所以不用担心scale永远都是1绘画尺寸永远不变的情况,只要不满足压缩后体积的要求
  65. 就会缩小绘画区域,早晚会有绘画区域小于图片尺寸的情况发生
  66. */
  67. if(maxSide>windowW){
  68. scale = windowW/maxSide
  69. }
  70. //trunc是去掉小数
  71. let imageW = Math.trunc(imageInfo.width*scale)
  72. let imageH = Math.trunc(imageInfo.height*scale)
  73. // console.log('调用压缩',imageW,imageH);
  74. //图片在规定绘画区域上画并获取新的图片的path
  75. getCanvasImage(canvasId,imagePath,imageW,imageH,
  76. (pressImgPath)=>{
  77. /*
  78. 再去检查是否满足要求,始终缩小绘画区域,让图片适配绘画区域
  79. 这里乘以0.95是必须的,如果不缩小绘画区域,会出现尺寸比绘画区域小,
  80. 而体积比要求压缩体积大的情况出现,就会无穷递归下去,因为scale的值永远是1
  81. 但0.95不是固定的,你可以根据需要自己改,0到1之间,越小则绘画区域缩小的越快
  82. 但不建议取得太小,绘画区域缩小的太快,压出来的将总是很糊的
  83. */
  84. getLessLimitSizeImage(canvasId,pressImgPath,limitSize,drawWidth*0.95,callback);
  85. }
  86. )
  87. }
  88. })
  89. }
  90. )
  91. }
  92. export default getLessLimitSizeImage