博客列表 >微信小程序压缩图片并上传

微信小程序压缩图片并上传

搁浅
搁浅原创
2022年10月12日 14:23:49973浏览

wxml

  1. <canvas canvas-id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}rpx;height:{{imageH}}rpx;top:-9999px;left:-9999px;"></canvas>
  2. <view style="text-align: center;"><image style="width: 192rpx;height: 192rpx;border-radius: 500rpx !important;overflow: hidden; margin-top: 30rpx;margin-bottom: 30rpx;" src="{{returnImage}}"></image></view>
  3. <view style="display: flex;">
  4. <button type="primary" bindtap="getImageInfo">头像预览</button>
  5. <button type="primary" bindtap="upload" loading="{{isdisabled}}" disabled="{{isdisabled}}">上传头像</button>
  6. </view>

js

  1. const app = getApp();
  2. // 手机的宽度
  3. var windowWRPX = 750
  4. var pixelRatio = wx.getSystemInfoSync().pixelRatio
  5. Page({
  6. /**
  7. * 页面的初始数据
  8. */
  9. data: {
  10. topLabel: '头像上传', //顶部栏
  11. triggered: false, //模块是否刷新中
  12. isdisabled: false, //是否提交
  13. showmodel: false, //是否编辑模式
  14. imageSrc: '',
  15. returnImage: '',
  16. isShowImg: false,
  17. // 初始化的宽高
  18. cropperInitW: windowWRPX,
  19. cropperInitH: windowWRPX,
  20. // 动态的宽高
  21. cropperW: windowWRPX,
  22. cropperH: windowWRPX,
  23. // 动态的left top值
  24. cropperL: 0,
  25. cropperT: 0,
  26. // 图片缩放值
  27. scaleP: 0,
  28. imageW: 0,
  29. imageH: 0,
  30. // 裁剪框 宽高
  31. cutW: 0,
  32. cutH: 0,
  33. cutL: 0,
  34. cutT: 0,
  35. },
  36. upload(e) { //头像上传
  37. wx.showLoading({
  38. title: '头像上传中...',
  39. })
  40. this.setData({isdisabled:true})
  41. const userinfo = wx.getStorageSync('userinfo')
  42. let encryptor = new Encrypt.JSEncrypt()
  43. encryptor.setPublicKey(publicKey);
  44. let requestkey = encryptor.encrypt(userinfo.YHBH + ',' + userinfo.OPENID + ',' + userinfo.BH + ',' + new Date().getTime()) // 加密
  45. // 将图片写入画布
  46. const ctx = wx.createCanvasContext('myCanvas')
  47. ctx.drawImage(this.data.imageSrc)
  48. ctx.draw(true, () => {
  49. // 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题
  50. let canvasW = (this.data.cutW / this.data.cropperW) * (this.data.imageW / pixelRatio)
  51. let canvasH = (this.data.cutH / this.data.cropperH) * (this.data.imageH / pixelRatio)
  52. let canvasL = (this.data.cutL / this.data.cropperW) * (this.data.imageW / pixelRatio)
  53. let canvasT = (this.data.cutT / this.data.cropperH) * (this.data.imageH / pixelRatio)
  54. setTimeout(() => {
  55. wx.canvasToTempFilePath({
  56. x: canvasL,
  57. y: canvasT,
  58. width: canvasW,
  59. height: canvasH,
  60. destWidth: canvasW * 0.35,//设置压缩百分比,如果写100就是分辨率
  61. destHeight: canvasH * 0.35,//设置压缩百分比,如果写100就是分辨率
  62. canvasId: 'myCanvas',
  63. fileType: 'jpg',
  64. success: res => {
  65. wx.uploadFile({
  66. url: App.uploads + '/weixin/upload/img/upload/cover',
  67. filePath: res.tempFilePath,
  68. name: 'file',
  69. header: {
  70. token: requestkey
  71. },
  72. formData: {
  73. BH: wx.getStorageSync('userinfo').BH
  74. },
  75. success:res=>{
  76. res.data = JSON.parse(res.data)
  77. let pages = getCurrentPages();
  78. let previousPage = pages[pages.length - 2]; //上一个页面
  79. previousPage.setData({
  80. avatarUrl: res.data.data.filePath
  81. })
  82. const userinfo = wx.getStorageSync('userinfo')
  83. userinfo.TX = res.data.data.filePath
  84. wx.setStorageSync('userinfo', userinfo)
  85. wx.hideLoading()
  86. wx.showToast({
  87. title: '上传成功',
  88. icon: "succes",
  89. duration: 1500
  90. })
  91. this.setData({isdisabled:false})
  92. },
  93. fail:res=>{
  94. this.setData({isdisabled:false})
  95. wx.hideLoading()
  96. wx.showToast({
  97. title: '上传失败',
  98. icon: "error",
  99. duration: 1500
  100. })
  101. }
  102. })
  103. }
  104. })
  105. }, 500);
  106. })
  107. },
  108. // 获取图片
  109. getImageInfo() {
  110. wx.showLoading({
  111. title: '图片生成中...',
  112. })
  113. wx.downloadFile({
  114. url: this.data.imageSrc, //仅为示例,并非真实的资源
  115. success: res=>{
  116. // 将图片写入画布
  117. const ctx = wx.createCanvasContext('myCanvas')
  118. ctx.drawImage(res.tempFilePath)
  119. ctx.draw(true, () => {
  120. // 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题
  121. let canvasW = (this.data.cutW / this.data.cropperW) * (this.data.imageW / pixelRatio)
  122. let canvasH = (this.data.cutH / this.data.cropperH) * (this.data.imageH / pixelRatio)
  123. let canvasL = (this.data.cutL / this.data.cropperW) * (this.data.imageW / pixelRatio)
  124. let canvasT = (this.data.cutT / this.data.cropperH) * (this.data.imageH / pixelRatio)
  125. setTimeout(() => {
  126. wx.canvasToTempFilePath({
  127. x: canvasL,
  128. y: canvasT,
  129. width: canvasW,
  130. height: canvasH,
  131. destWidth: canvasW * 0.35,//设置压缩百分比,如果写100就是分辨率
  132. destHeight: canvasH * 0.35,//设置压缩百分比,如果写100就是分辨率
  133. canvasId: 'myCanvas',
  134. fileType: 'jpg',
  135. success: res=>{
  136. wx.hideLoading()
  137. // wx.getImageInfo({
  138. // src: res.tempFilePath,
  139. // success (res) {
  140. // console.log(res.width)//图片宽
  141. // console.log(res.height)//图片高
  142. // }
  143. // })
  144. // 成功获得地址的地方
  145. wx.previewImage({
  146. current: '', // 当前显示图片的http链接
  147. urls: [res.tempFilePath] // 需要预览的图片http链接列表
  148. })
  149. this.setData({
  150. returnImage:res.tempFilePath
  151. })
  152. }
  153. })
  154. }, 200);
  155. })
  156. }
  157. })
  158. },
  159. /**
  160. * 生命周期函数--监听页面加载
  161. */
  162. onLoad: function (options) {
  163. this.setData({
  164. imageSrc: 'https://wx3.sinaimg.cn/orj360/6b03f0e6gy1h6c1mivf4lj20u01400wu.jpg'
  165. })
  166. },
  167. /**
  168. * 生命周期函数--监听页面初次渲染完成
  169. */
  170. onReady: function () {
  171. wx.showLoading({
  172. title: '图片加载中...',
  173. })
  174. wx.getImageInfo({
  175. src: this.data.imageSrc,
  176. success: res=>{
  177. var innerAspectRadio = res.width / res.height;
  178. // 根据图片的宽高显示不同的效果 保证图片可以正常显示
  179. if (innerAspectRadio >= 1) {
  180. this.setData({
  181. cropperW: windowWRPX,
  182. cropperH: windowWRPX / innerAspectRadio,
  183. // 初始化left right
  184. cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),
  185. cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),
  186. // 裁剪框 宽高
  187. cutW: windowWRPX,
  188. cutH: windowWRPX / innerAspectRadio,
  189. cutL: 0,
  190. cutT: 0,
  191. // 图片缩放值
  192. scaleP: res.width * pixelRatio / windowWRPX,
  193. // 图片原始宽度 rpx
  194. imageW: res.width * pixelRatio,
  195. imageH: res.height * pixelRatio
  196. })
  197. } else {
  198. this.setData({
  199. cropperW: windowWRPX * innerAspectRadio,
  200. cropperH: windowWRPX,
  201. // 初始化left right
  202. cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),
  203. cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),
  204. // 裁剪框的宽高
  205. cutW: windowWRPX * innerAspectRadio,
  206. cutH: windowWRPX,
  207. cutL: 0,
  208. cutT: 0,
  209. // 图片缩放值
  210. scaleP: res.width * pixelRatio / windowWRPX,
  211. // 图片原始宽度 rpx
  212. imageW: res.width * pixelRatio,
  213. imageH: res.height * pixelRatio
  214. })
  215. }
  216. this.setData({
  217. isShowImg: true
  218. })
  219. wx.hideLoading()
  220. }
  221. })
  222. },
  223. /**
  224. * 生命周期函数--监听页面显示
  225. */
  226. onShow: function () {
  227. },
  228. /**
  229. * 生命周期函数--监听页面隐藏
  230. */
  231. onHide: function () {
  232. },
  233. /**
  234. * 生命周期函数--监听页面卸载
  235. */
  236. onUnload: function () {
  237. },
  238. /**
  239. * 页面相关事件处理函数--监听用户下拉动作
  240. */
  241. onPullDownRefresh: function () {
  242. },
  243. /**
  244. * 页面上拉触底事件的处理函数
  245. */
  246. onReachBottom: function () {
  247. },
  248. /**
  249. * 用户点击右上角分享
  250. */
  251. onShareAppMessage: function () {
  252. }
  253. })

实际应用场景

html

  1. <canvas canvas-id="myCanvas" style="position:absolute;border: 1px solid red; width:{{imageW}}rpx;height:{{imageH}}rpx;top:-9999px;left:-9999px;"></canvas>
  2. <button class="round cu-avatar" plain="true" open-type="chooseAvatar" bind:chooseavatar="getimginfo" style="border: 0;width: 158rpx;height: 158rpx;">
  3. <image class="round" src="https://wx3.sinaimg.cn/orj360/6b03f0e6gy1h6c1mivf4lj20u01400wu.jpg" style="width: 158rpx;height: 158rpx;"></image>
  4. </button>

js

  1. const app = getApp();
  2. // 手机的宽度
  3. var windowWRPX = 750
  4. var pixelRatio = wx.getSystemInfoSync().pixelRatio
  5. Page({
  6. /**
  7. * 页面的初始数据
  8. */
  9. data: {
  10. topLabel: '头像上传', //顶部栏
  11. // 初始化的宽高
  12. cropperInitW: windowWRPX,
  13. cropperInitH: windowWRPX,
  14. // 动态的宽高
  15. cropperW: windowWRPX,
  16. cropperH: windowWRPX,
  17. // 动态的left top值
  18. cropperL: 0,
  19. cropperT: 0,
  20. // 图片缩放值
  21. scaleP: 0,
  22. imageW: 0,
  23. imageH: 0,
  24. // 裁剪框 宽高
  25. cutW: 0,
  26. cutH: 0,
  27. cutL: 0,
  28. cutT: 0,
  29. },
  30. getimginfo(e) { //获取图片信息
  31. wx.getImageInfo({
  32. src: e.detail.avatarUrl,
  33. success: res => {
  34. var innerAspectRadio = res.width / res.height;
  35. // 根据图片的宽高显示不同的效果 保证图片可以正常显示
  36. if (innerAspectRadio >= 1) {
  37. this.setData({
  38. cropperW: windowWRPX,
  39. cropperH: windowWRPX / innerAspectRadio,
  40. // 初始化left right
  41. cropperL: Math.ceil((windowWRPX - windowWRPX) / 2),
  42. cropperT: Math.ceil((windowWRPX - windowWRPX / innerAspectRadio) / 2),
  43. // 裁剪框 宽高
  44. cutW: windowWRPX,
  45. cutH: windowWRPX / innerAspectRadio,
  46. cutL: 0,
  47. cutT: 0,
  48. // 图片缩放值
  49. scaleP: res.width * pixelRatio / windowWRPX,
  50. // 图片原始宽度 rpx
  51. imageW: res.width * pixelRatio,
  52. imageH: res.height * pixelRatio
  53. })
  54. } else {
  55. this.setData({
  56. cropperW: windowWRPX * innerAspectRadio,
  57. cropperH: windowWRPX,
  58. // 初始化left right
  59. cropperL: Math.ceil((windowWRPX - windowWRPX * innerAspectRadio) / 2),
  60. cropperT: Math.ceil((windowWRPX - windowWRPX) / 2),
  61. // 裁剪框的宽高
  62. cutW: windowWRPX * innerAspectRadio,
  63. cutH: windowWRPX,
  64. cutL: 0,
  65. cutT: 0,
  66. // 图片缩放值
  67. scaleP: res.width * pixelRatio / windowWRPX,
  68. // 图片原始宽度 rpx
  69. imageW: res.width * pixelRatio,
  70. imageH: res.height * pixelRatio
  71. })
  72. }
  73. this.upfile(e.detail.avatarUrl)
  74. }
  75. })
  76. },
  77. upfile(url) { //上传图片
  78. wx.getFileInfo({
  79. filePath: url,
  80. success: res => {
  81. if (res.size > 10000) { //大于10KB就压缩
  82. const ctx = wx.createCanvasContext('myCanvas')
  83. ctx.drawImage(url)
  84. ctx.draw(true, () => {
  85. // 获取画布要裁剪的位置和宽度 均为百分比 * 画布中图片的宽度 保证了在微信小程序中裁剪的图片模糊 位置不对的问题
  86. let canvasW = (this.data.cutW / this.data.cropperW) * (this.data.imageW / pixelRatio)
  87. let canvasH = (this.data.cutH / this.data.cropperH) * (this.data.imageH / pixelRatio)
  88. let canvasL = (this.data.cutL / this.data.cropperW) * (this.data.imageW / pixelRatio)
  89. let canvasT = (this.data.cutT / this.data.cropperH) * (this.data.imageH / pixelRatio)
  90. setTimeout(() => {
  91. wx.canvasToTempFilePath({
  92. x: canvasL,
  93. y: canvasT,
  94. width: canvasW,
  95. height: canvasH,
  96. destWidth: canvasW * 0.35, //设置压缩百分比,如果写100就是分辨率
  97. destHeight: canvasH * 0.35, //设置压缩百分比,如果写100就是分辨率
  98. canvasId: 'myCanvas',
  99. fileType: 'jpg',
  100. success: res => {
  101. wx.uploadFile({
  102. url: App.uploads + '/file/api/upload',
  103. filePath: res.tempFilePath,
  104. name: 'file',
  105. header: {
  106. authToken: wx.getStorageSync('token'),
  107. },
  108. success: res => {
  109. res.data = JSON.parse(res.data)
  110. this.data.tx = res.data.data.filePath
  111. this.batchmodify()
  112. },
  113. fail: res => {
  114. wx.hideLoading()
  115. wx.showToast({
  116. title: '上传失败',
  117. icon: "error",
  118. duration: 1500
  119. })
  120. }
  121. })
  122. }
  123. })
  124. }, 500);
  125. })
  126. } else {
  127. wx.uploadFile({
  128. url: App.uploads + '/file/api/upload',
  129. filePath: url,
  130. name: 'file',
  131. header: {
  132. authToken: wx.getStorageSync('token'),
  133. },
  134. success: res => {
  135. res.data = JSON.parse(res.data)
  136. this.data.tx = res.data.data.filePath
  137. this.batchmodify()
  138. },
  139. fail: res => {
  140. wx.hideLoading()
  141. wx.showToast({
  142. title: '上传失败',
  143. icon: "error",
  144. duration: 1500
  145. })
  146. }
  147. })
  148. }
  149. }
  150. })
  151. },
  152. /**
  153. * 生命周期函数--监听页面加载
  154. */
  155. onLoad: function (options) {
  156. },
  157. /**
  158. * 生命周期函数--监听页面初次渲染完成
  159. */
  160. onReady: function () {
  161. },
  162. /**
  163. * 生命周期函数--监听页面显示
  164. */
  165. onShow: function () {
  166. },
  167. /**
  168. * 生命周期函数--监听页面隐藏
  169. */
  170. onHide: function () {
  171. },
  172. /**
  173. * 生命周期函数--监听页面卸载
  174. */
  175. onUnload: function () {
  176. },
  177. /**
  178. * 页面相关事件处理函数--监听用户下拉动作
  179. */
  180. onPullDownRefresh: function () {
  181. },
  182. /**
  183. * 页面上拉触底事件的处理函数
  184. */
  185. onReachBottom: function () {
  186. },
  187. /**
  188. * 用户点击右上角分享
  189. */
  190. onShareAppMessage: function () {
  191. }
  192. })

css

  1. .round {
  2. border-radius: 5000rpx !important;
  3. overflow: hidden;
  4. }
  5. .cu-avatar {
  6. font-variant: small-caps;
  7. margin: 0;
  8. padding: 0;
  9. display: inline-flex;
  10. text-align: center;
  11. justify-content: center;
  12. align-items: center;
  13. background-color: #ccc;
  14. color: var(--white);
  15. white-space: nowrap;
  16. position: relative;
  17. width: 64rpx;
  18. height: 64rpx;
  19. background-size: cover;
  20. background-position: center;
  21. vertical-align: middle;
  22. font-size: 1.5em;
  23. }
声明:本文内容转载自脚本之家,由网友自发贡献,版权归原作者所有,如您发现涉嫌抄袭侵权,请联系admin@php.cn 核实处理。
全部评论
文明上网理性发言,请遵守新闻评论服务协议