微信小程序里在canvas里使用base64的图片
wxml 文件:
1 <!-- <view class="admin-qrcode"> 2 <image src="{{adminQrcode}}" /> 3 4 </view> 5 <view class="admin-info"> 6 <view class="admin-info-no"> 7 账号:10086 8 </view> 9 <view class="admin-info-pwd"> 10 密码:10086 11 </view> 12 </view> --> 13 <view wx:if="is_hide_canvas"> 14 <canvas style="width: 320px; height: 400px; left:{{(screenWidth-320)/2}}px;top:20px;" canvas-id="myCanvas"></canvas> 15 </view> 16 17 <!-- <button bindtap="survived">生成</button> --> 18 19 20 <view class="oper-btn"> 21 <view class="oper-save" bindtap="saveToLoacl"> 22 <view> 23 <text class="iconfont icon-download oper-icon-save"></text> 24 </view> 25 <view> 26 保存 27 </view> 28 </view> 29 <view class="oper-share" bindtap="toShare"> 30 <button open-type="share" class="share-btn"> 31 <view> 32 <text class="iconfont icon-weixin oper-icon-share"></text> 33 </view> 34 <view> 35 微信好友 36 </view> 37 </button> 38 </view> 39 </view> 40 41 <!-- <button bindtap="saveToLoacl">保存</button> -->
js 文件:
1 const app = getApp(); 2 const http = require('../../../utils/http.js'); 3 const api = require('../../../config.js'); 4 const utils = require('../../../utils/util.js'); 5 6 Page({ 7 8 /** 9 * 页面的初始数据 10 */ 11 data: { 12 adminQrcode: '', 13 codeImg: '../../../image/shang.png', 14 is_hide_canvas: false, 15 tempFilePath: '', 16 basepath: '', 17 screenWidth: app.globalData.screenWidth 18 19 }, 20 21 22 getAdminQrcode: function() { 23 let _this = this; 24 let postData = { 25 'scene': '10086', 26 'page': 'pages/index/index', 27 'is_hyaline': '0' 28 }; 29 30 wx.showLoading({ 31 title: '数据请求中...', 32 mask: true 33 }) 34 35 http.httpPost(api.CreateQrcode, postData, (res) => { 36 console.log(res); 37 wx.hideLoading(); 38 if (!res) { 39 return; 40 } 41 42 if (res.success) { 43 let _result = res.result; 44 if (_result.success) { 45 46 47 this.setData({ 48 adminQrcode: 'data:image/png;base64,' + _result.data 49 }); 50 this.survived(); 51 52 53 } else { 54 utils.showToastMessage(_result); 55 } 56 } else { 57 utils.showToastMessage(res); 58 } 59 60 }); 61 }, 62 63 /** 64 * 生命周期函数--监听页面加载 65 */ 66 onLoad: function(options) { 67 if (options.admin_no && options.admin_pwd) { 68 this.setData({ 69 admin_no: options.admin_no, 70 admin_pwd: options.admin_pwd 71 }); 72 this.getAdminQrcode(); 73 } else { 74 wx.showModal({ 75 title: '提示', 76 content: '参数异常', 77 showCancel: false, 78 success: res => { 79 wx.navigateBack({ 80 81 }) 82 } 83 }) 84 } 85 86 87 }, 88 89 /** 90 * 生命周期函数--监听页面初次渲染完成 91 */ 92 onReady: function() { 93 94 }, 95 96 97 /** 98 * 生命周期函数--监听页面显示 99 */ 100 onShow: function() { 101 102 }, 103 104 /** 105 * 生命周期函数--监听页面隐藏 106 */ 107 onHide: function() { 108 109 }, 110 111 /** 112 * 生命周期函数--监听页面卸载 113 */ 114 onUnload: function() { 115 116 }, 117 118 /** 119 * 页面相关事件处理函数--监听用户下拉动作 120 */ 121 onPullDownRefresh: function() { 122 123 }, 124 125 /** 126 * 页面上拉触底事件的处理函数 127 */ 128 onReachBottom: function() { 129 130 }, 131 132 saveToLoacl: function() { 133 let _this = this; 134 const fsm = wx.getFileSystemManager(); 135 wx.saveImageToPhotosAlbum({ 136 filePath: _this.data.tempFilePath, 137 success(res) { 138 fsm.readdir({ // 读取目录内文件列表 139 dirPath: _this.data.basepath, 140 success(res) { 141 res.files.forEach((val) => { // 遍历文件列表里的数据 142 console.log(val) 143 fsm.unlink({ // 清除writeFile保存的图片 144 filePath: _this.data.basepath + '/' + val 145 }); 146 }) 147 }, 148 fail(err) { 149 console.log(err) 150 wx.showModal({ 151 title: '异常', 152 content: JSON.stringify(err), 153 showCancel: false 154 }) 155 } 156 }) 157 // wx.getSavedFileList({ 158 // success: savedFileInfo => { 159 // let list = savedFileInfo.fileList 160 // console.log("list:", savedFileInfo.fileList) 161 // for (let i = 0; i < list.length; i++) { 162 // wx.removeSavedFile({ 163 // filePath: list[i].filePath, 164 // }) 165 // } 166 // } 167 // }) 168 wx.showModal({ 169 title: '提示', 170 content: '图片保存成功,可在相册中查看', 171 showCancel: false, 172 }) 173 }, 174 175 fail(res) { 176 wx.hideLoading() 177 wx.showModal({ 178 title: '提示', 179 content: '图片保存失败,请重试', 180 showCancel: false 181 }) 182 } 183 }) 184 }, 185 toShare: function() { 186 wx.showToast({ 187 title: '请点击右上角分享按钮', 188 icon: "none" 189 }) 190 191 }, 192 193 /** 194 * 用户点击右上角分享 195 */ 196 onShareAppMessage: function(e) { 197 console.log(e); 198 let _this = this; 199 let share_type = e.from; 200 return { 201 title: '账号:' + _this.data.admin_no + " 密码:" + _this.data.admin_pwd, 202 path: '/pages/Admin/BindAdmin/BindAdmin?admin_no=' + _this.data.admin_no + '&admin_pwd=' + _this.data.admin_pwd 203 }; 204 }, 205 survived: function() { 206 let vm = this 207 // 创建画布对象 208 const ctx = wx.createCanvasContext("myCanvas", vm) 209 // base64格式图片转本地文件 210 const fsm = wx.getFileSystemManager(); 211 const timestamp = Date.parse(new Date()); // 先创建时间戳用来命名(不加时间戳在画连续画第二张图的时候有问题) 212 timestamp: timestamp / 1000 213 const FILE_BASE_NAME = 'tmp_base64' + timestamp; //自定义文件名 因第二张图相同名字读取第一张故加个时间戳 214 console.log(FILE_BASE_NAME) 215 var base64data = vm.properties.adminQrcode; //base64格式图片 216 const [, format, bodyData] = /data:image\/(\w+);base64,(.*)/.exec(base64data) || []; 217 if (!format) { 218 return (new Error('ERROR_BASE64SRC_PARSE')); 219 } 220 const filePath = `${wx.env.USER_DATA_PATH}/${FILE_BASE_NAME}.${format}`; 221 const buffer = wx.base64ToArrayBuffer(bodyData); 222 console.log(filePath) 223 fsm.writeFile({ 224 filePath, 225 data: buffer, 226 encoding: 'binary', 227 success() { 228 filePath; 229 }, 230 fail() { 231 return (new Error('ERROR_BASE64SRC_WRITE')); 232 }, 233 }); 234 console.log(filePath) 235 console.log(wx.env.USER_DATA_PATH) 236 const basepath = `${wx.env.USER_DATA_PATH}` 237 238 vm.setData({ 239 basepath: basepath 240 }); 241 // console.log(filePath === filePath) 242 // console.log(filePath) 243 setTimeout(() => { 244 wx.getImageInfo({ 245 src: filePath, 246 success: function(res) { 247 // 根据 图片的大小 绘制底图 的大小 248 console.log(res) // 绘制底图的图片信息", 249 let imgW = res.width 250 let imgH = res.height 251 let imgPath = res.path 252 vm.setData({ 253 canvasHeight: imgH, 254 canvasWidth: imgW 255 }) 256 // 绘制底图 用原图的宽高比绘制 257 ctx.drawImage(imgPath, 0, 0, 320, 320) 258 // let srclogo = vm.data.codeImg // logo图片的路径 259 // // 绘制logo 260 // ctx.drawImage(srclogo, 12, imgH - 56, 240, 38) 261 262 ctx.setFontSize(14) 263 ctx.setFillStyle('#474B5B') 264 ctx.fillText('账号:' + vm.data.admin_no, 100, 340) 265 ctx.fillText('密码:' + vm.data.admin_pwd, 100, 370); 266 267 ctx.draw() 268 wx.showLoading({ 269 title: '获取图片中...', 270 mask: true 271 }) 272 setTimeout(() => { 273 wx.canvasToTempFilePath({ 274 canvasId: 'myCanvas', 275 success: function(res) { 276 console.log(res) // 合成的带有logo得图片 277 let tempFilePath = res.tempFilePath 278 // 保存到相册 279 console.log(tempFilePath); 280 vm.setData({ 281 tempFilePath: tempFilePath 282 }); 283 wx.hideLoading() 284 return; 285 wx.saveImageToPhotosAlbum({ 286 filePath: tempFilePath, 287 success(res) { 288 fsm.readdir({ // 读取目录内文件列表 289 dirPath: basepath, 290 success(res) { 291 res.files.forEach((val) => { // 遍历文件列表里的数据 292 console.log(val) 293 fsm.unlink({ // 清除writeFile保存的图片 294 filePath: basepath + '/' + val 295 }); 296 }) 297 }, 298 fail(err) { 299 console.log(err) 300 } 301 }) 302 // wx.getSavedFileList({ 303 // success: savedFileInfo => { 304 // let list = savedFileInfo.fileList 305 // console.log("list:", savedFileInfo.fileList) 306 // for (let i = 0; i < list.length; i++) { 307 // wx.removeSavedFile({ 308 // filePath: list[i].filePath, 309 // }) 310 // } 311 // } 312 // }) 313 wx.showModal({ 314 title: '提示', 315 content: '图片保存成功,可在相册中查看', 316 showCancel: false, 317 }) 318 }, 319 320 fail(res) { 321 wx.hideLoading() 322 wx.showModal({ 323 title: '提示', 324 content: '图片保存失败,请重试', 325 showCancel: false 326 }) 327 } 328 }) 329 } 330 }, vm) 331 }, 1000) 332 }, 333 fail(res) { 334 wx.hideLoading() 335 wx.showModal({ 336 title: '提示', 337 content: '图片信息获取失败,请重试', 338 showCancel: false 339 }) 340 } 341 }) 342 }, 100) 343 }, 344 345 })
wxss 文件
1 page { 2 background: #fff; 3 } 4 5 .admin-qrcode { 6 width: 100%; 7 text-align: center; 8 margin-top: 20px; 9 } 10 11 .admin-qrcode image { 12 height: 320px; 13 width: 320px; 14 } 15 16 .admin-info { 17 } 18 19 .admin-info-no { 20 height: 30px; 21 line-height: 30px; 22 text-align: center; 23 margin-top: 10px; 24 } 25 26 .admin-info-pwd { 27 height: 30px; 28 line-height: 30px; 29 text-align: center; 30 margin-top: 10px; 31 } 32 33 .oper-btn { 34 width: 100%; 35 text-align: center; 36 display: -webkit-flex; 37 margin-top: 40px; 38 color: #424656; 39 font-size: 14px; 40 } 41 42 .oper-save { 43 width: 50%; 44 text-align: center; 45 height: 60px; 46 line-height: 30px; 47 margin-top: 30px; 48 } 49 50 .oper-share { 51 width: 50%; 52 text-align: center; 53 height: 60px; 54 line-height: 30px; 55 } 56 57 .oper-icon-save { 58 font-size: 36px; 59 color: #2276ff; 60 } 61 62 .oper-icon-share { 63 font-size: 36px; 64 color: #3cb035; 65 } 66 67 .share-btn { 68 border: none; 69 background: #fff; 70 font-size: 14px; 71 display: inline; 72 line-height: 30px; 73 } 74 75 button::after { 76 border: none; 77 }