美文网首页Uniapp
uniapp开发微信小程序canvas生成分享海报 , 一键保存

uniapp开发微信小程序canvas生成分享海报 , 一键保存

作者: zkzhengmeng | 来源:发表于2022-01-21 12:47 被阅读0次

    1.注意事项 canvas中使用的网络图片地址, 必须在微信小程序后台设置下载白名单 , 就是后台返回的url地址域名

    2.微信头像域名也要设置下载白名单 , 就是获取到头像url地址的域名(https://thirdwx.qlogo.cn 或者 https://wx.qlogo.cn)

    3.canvas中直接使用微信头像地址会报错 , 需要使用 wx.downloadFile把微信头像地址下载下来转换成临时地址, 然后在ctx.drawImage中使用

    <template>
     <view>
        <view @click="handleShowPoster">生成海报</view>
    <uni-popup ref="haibao" type="bottom">
             <view class="haibao_cent">
                 <image  style="width: 96%; height:90vh;margin-left: 2%;" @click="shibie(canvasToTempFilePath)" :src="canvasToTempFilePath" mode=""></image>
                 <view class="saveFn">
                     <view @click="saveShareImg(canvasToTempFilePath)">保存图片</view>
                     <view @click="handleCancel">取 消</view>
                 </view>
             </view>
         </uni-popup>
    </view>
    </template>
    <script>
    export default {
     data() {
         return {
             userName:'微信昵称111',
             codeUrl : 'https://gx.cnncb.com/api/order/hx_qrcode.html?order_no=16424131343910&shop_id=1&time=1642413134',
             coverUrl : 'https://thirdwx.qlogo.cn/mmopen/vi_32/geD3fBVGs5X4kcAkV2Nd56IAAtF8mr5cOQgLaCGoYiaszKv11UPhicltOEAQm6RUNX4gOicS0owicmp9NjqkT3Lxqw/132',
             headUrl : 'https://gx.cnncb.com/132.jpg',
             ratio: 1,
             ctx: null, // 创建canvas对象
             canvasToTempFilePath: null, // 保存最终生成的导出的图片地址
             openStatus: true // 声明一个全局变量判断是否授权保存到相册
         }
     },
       onShow() {
    
         this.getUserInfo();
     },
     methods: {
         handleShowPoster() {
            this.$refs.haibao.open();
         },
         handleCancel() {
         this.$refs.haibao.close();
         },
     
         getUserInfo(){
             this.$api.userInfo().then(res =>{
                  wx.downloadFile({//下载
                     url: res.data.avatar,//服务器上的pdf地址
                     success: function (res1) {
                       //console.log('头像临时地址',res1)
                       that.headUrl = res1.tempFilePath
                     }
                 })
             })
         },
         shibie(url){
             wx.previewImage({
                 current: url, // 当前显示图片的http链接  
                 urls: [url], // 需要预览的图片http链接列表  
             })
         },
         // 生成海报
         async createCanvasImage() {
             let self = this;
             // 点击生成海报数据埋点
             if (!self.ctx) {
             
                 wx.showLoading({
                     title: '生成中...'
                 });
                 let code = new Promise(function(resolve) {
                     wx.getImageInfo({
                         src: that.codeUrl,
                         success: function(res) {
                             resolve(res.path);
                         },
                         fail: function(err) {
                             console.log(err);
                             wx.showToast({
                                 title: '网络错误请重试',
                                 icon: 'loading'
                             });
                         }
                     });
                 });
                 
                 let cover = new Promise(function(resolve) {
                     wx.getImageInfo({
                         src: that.coverUrl,
                         success: function(res) {
                             resolve(res.path);
                         },
                         fail: function(err) {
                             console.log(err);
                             wx.showToast({
                                 title: '网络错误请重试',
                                 icon: 'loading'
                             });
                         }
                     });
                 });
          
                 // 头像
                 let headImg = new Promise(function(resolve) {
                     wx.getImageInfo({
                         src: that.headUrl,
                         success: function(res) {
                             resolve(res.path);
                         },
                         fail: function(err) {
                             console.log(err);
                             wx.showToast({
                                 title: '网络错误请重试',
                                 icon: 'loading'
                             });
                         }
                     });
                 });
          
                 Promise.all([headImg, code,cover]).then(function(result) {
                     const ctx = wx.createCanvasContext('myCanvas');
                     console.log(ctx, self.ratio, 'ctx');
                     let canvasWidthPx = 690 * self.ratio,
                         canvasHeightPx = 1040 * self.ratio,
                         
                         avatarurl_width = 110, //绘制的头像宽度
                         avatarurl_heigth = 110, //绘制的头像高度
                         avatarurl_x =65, //绘制的头像在画布上的位置
                         avatarurl_y = 15, //绘制的头像在画布上的位置
                         
                         codeurl_width = 180, //绘制的二维码宽度
                         codeurl_heigth = 180, //绘制的二维码高度
                         codeurl_x = 450, //绘制的二维码在画布上的位置
                         codeurl_y = 680, //绘制的二维码在画布上的位置
                         
                         coverurl_width = 610, //绘制的封面宽度
                         coverurl_heigth = 500, //绘制的封面高度
                         coverurl_x = 40, //绘制的封面在画布上的位置
                         coverurl_y = 160; //绘制的封面在画布上的位置
                         
                     ctx.drawImage('/static/hbbj.png', 0, 0, 690, 1040); // 背景图片需要本地
                     
                     // 白底
                     ctx.setFillStyle('#ffffff')
                     ctx.fillRect(25, 150, 640, 900)
                     
                     ctx.save(); // 先保存状态 已便于画完圆再用
                     ctx.beginPath(); //开始绘制
                     //先画个圆   前两个参数确定了圆心 (x,y) 坐标  第三个参数是圆的半径  四参数是绘图方向  默认是false,即顺时针
                     ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
                     ctx.clip(); //画了圆 再剪切  原始画布中剪切任意形状和尺寸。一旦剪切了某个区域,则所有之后的绘图都会被限制在被剪切的区域内
                     ctx.drawImage(result[0], avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth); // 推进去图片
          
                     ctx.restore(); //恢复之前保存的绘图上下文状态 可以继续绘制
                     
                     ctx.font = 'normal bold 35px sans-serif';
                     ctx.setFillStyle('#ffffff'); // 文字颜色
                     ctx.fillText(that.userName, 240, 65); // 绘制文字
          
                     ctx.setFillStyle('#ffffff'); // 文字颜色
                     ctx.setFontSize(30); // 文字字号
                     ctx.fillText('向您推荐精美商品', 240, 110); // 绘制文字
                     // 白底
                      ctx.setFillStyle('#CBE6FE')
                      ctx.fillRect(28, 880, 636, 160)
                      ctx.drawImage('/static/logo.png', 70, 900, 120, 120); // 背景图片需要本地
                      ctx.font = 'normal bold 30px sans-serif';
                      ctx.setFillStyle('#222222');
                      ctx.fillText('郑州知网文化传播有限公司', 220, 950);
                      ctx.font = 'normal normal 26px sans-serif';
                      ctx.setFillStyle('#666666'); // 文字颜色
                      ctx.fillText('郑州市紫荆山路62号兴达国贸2416室', 220, 1000); // 绘制文字
                      ctx.beginPath();
                     // 设置线宽
                     // ctx.lineWidth = 1;
                     // // 设置间距(参数为无限数组,虚线的样式会随数组循环)
                     // ctx.setLineDash([10, 10]);
                     // // 移动画笔至坐标 x20 y20 的位置
                     // ctx.moveTo(30, 830);
                     // // 绘制到坐标 x20 y100 的位置
                     // ctx.lineTo(660, 830);
                     // // 填充颜色
                     // ctx.strokeStyle="#aaaaaa";
                     // 开始填充
                     ctx.stroke();
                     ctx.closePath();
                     
                     ctx.font = 'normal normal 36px sans-serif';
                     ctx.setFillStyle('#E65449'); // 文字颜色
                     ctx.fillText('长按识别', 40, 740); // 绘制孩子百分比
                     
                     ctx.font = 'normal normal 36px sans-serif';
                     ctx.setFillStyle('#222222'); // 文字颜色
                     ctx.fillText('小程序码', 200, 740); // 绘制孩子百分比
                     
                     ctx.font = 'normal normal 36px sans-serif';
                     ctx.setFillStyle('#222222'); // 文字颜色
                     ctx.fillText('查看商品详情信息', 50, 800); // 绘制孩子百分比
                     console.log('result[1]',result[1])
                     ctx.drawImage(result[2], coverurl_x, coverurl_y, coverurl_width, coverurl_heigth); // 绘制封面
                     ctx.drawImage(result[1], codeurl_x, codeurl_y, codeurl_width, codeurl_heigth); // 绘制头像
                     ctx.draw(false, function() {
                         // canvas画布转成图片并返回图片地址
                         wx.canvasToTempFilePath({
                             canvasId: 'myCanvas',
                             success: function(res) {
                                 self.canvasToTempFilePath = res.tempFilePath;
                                 self.showShareImg = true;
                                 console.log(res.tempFilePath, 'canvasToTempFilePath');
                                 wx.showToast({
                                     title: '绘制成功'
                                 });
                             },
                             fail: function() {
                                 wx.showToast({
                                     title: '绘制失败'
                                 });
                             },
                             complete: function() {
                                 wx.hideLoading();
                                 wx.hideToast();
                             }
                         });
                     });
                 });
             }
         },
          // 保存到系统相册
          saveShareImg: function(canvasToTempFilePath) {
             let self = this;
             // 保存海报
             self.saveId = '保存海报';
             // 获取用户是否开启用户授权相册
             if (!self.openStatus) {
                 wx.openSetting({
                     success: result => {
                         if (result) {
                             if (result.authSetting['scope.writePhotosAlbum'] === true) {
                                 self.openStatus = true;
                                 self.$refs.haibao.close();
                                 wx.saveImageToPhotosAlbum({
                                     filePath: canvasToTempFilePath,
                                     success() {
                                         self.showShareImg = false;
                                         wx.showToast({
                                             title: '图片保存成功,快去分享到朋友圈吧~',
                                             icon: 'none',
                                             duration: 2000
                                         });
                                     },
                                     fail() {
                                         wx.showToast({
                                             title: '保存失败',
                                             icon: 'none'
                                         });
                                     }
                                 });
                             }
                         }
                     },
                     fail: () => {},
                     complete: () => {}
                 });
             } else {
                 wx.getSetting({
                     success(res) {
                         // 如果没有则获取授权
                         if (!res.authSetting['scope.writePhotosAlbum']) {
                             wx.authorize({
                                 scope: 'scope.writePhotosAlbum',
                                 success() {
                                     self.openStatus = true;
                                     wx.saveImageToPhotosAlbum({
                                         filePath: canvasToTempFilePath,
                                         success() {
                                             self.showShareImg = false;
                                             self.$refs.haibao.close();
                                             wx.showToast({
                                                 title: '图片保存成功,快去分享到朋友圈吧~',
                                                 icon: 'none',
                                                 duration: 2000
                                             });
                                         },
                                         fail() {
                                             wx.showToast({
                                                 title: '保存失败',
                                                 icon: 'none'
                                             });
                                         }
                                     });
                                 },
                                 fail() {
                                     // 如果用户拒绝过或没有授权,则再次打开授权窗口
                                     self.openStatus = false;
                                     console.log('请设置允许访问相册');
                                     wx.showToast({
                                         title: '请设置允许访问相册',
                                         icon: 'none'
                                     });
                                 }
                             });
                         } else {
                             // 有则直接保存
                             self.openStatus = true;
                             wx.saveImageToPhotosAlbum({
                                 filePath: canvasToTempFilePath,
                                 success() {
                                     self.showShareImg = false;
                                     wx.showToast({
                                         title: '图片保存成功,快去分享到朋友圈吧~',
                                         icon: 'none',
                                         duration: 2000
                                     });
                                 },
                                 fail() {
                                     wx.showToast({
                                         title: '保存失败',
                                         icon: 'none'
                                     });
                                 }
                             });
                         }
                     },
                     fail(err) {
                         console.log(err);
                     }
                 });
             }
          }
     },
    }
    </script>
    <style lang="scss" scoped>
    
     .haibao_cent{
         width: 100%;
         height: 100vh;
         .saveFn{
             padding: 0 3%;
             display: flex;
             margin-top: 10px;
             justify-content: space-between;
             view:nth-child(1){
                 width: 120px;
                 height: 40px;
                 padding: 0 10px;
                 line-height: 40px;
                 background-image: linear-gradient(to right, #FF582E, #FE462A, #FE2923, #FE0D1D);
                 text-align: center;
                 color:#FFFFFF;
                 border-radius: 20px;
             };
             view:nth-child(2){
                 width: 120px;
                 height: 40px;
                 padding: 0 10px;
                 line-height: 40px;
                 text-align: center;
                 color:#000;
                 border-radius: 20px;
                 font-weight: 600;
                 background-image: linear-gradient(to right, #e4d7d4, #cebebc, #e0d4d4, #efe3e5);
             }
         }
     }
    
     }
    </style>
    

    相关文章

      网友评论

        本文标题:uniapp开发微信小程序canvas生成分享海报 , 一键保存

        本文链接:https://www.haomeiwen.com/subject/bxuuhrtx.html