uni-app 微信小程序 保存当前页面为图片

由于在微信小程序环境下面没法获取dom,很多方法都很难去实现保存html结构的页面,比较有效的#painter 可以不需要操作dom,但是那玩意儿和重新用js写个页面一样,简单的页面还好,复杂的,元素比较多的就很麻烦,所以考虑用webview+html2canvas来完成

先说一下思路,既然在微信小程序环境下行不通,那就考虑换个环境,用webview加载页面,再通过html2canvas来生成相应的canvas,然后转成图片。

首先是webview,不懂的可以去看下官方文档,贴在这里:https://uniapp.dcloud.net.cn/component/web-view.html#web-view。也就是在小程序或者app环境中挂载一个ifram,小程序加载这个页面必须放到服务器上,其他像app的可以放在本地。

贴代码

//小程序端
<web-view :src="webUrl" @message="handleMessage"></web-view>
//webUrl -->页面路径     handleMessage-->页面像服务器通信的方法
<script>
export default{
  methods:{
    //
    saveImageToPhotosAlbum(data) {
      let base64 = data.replace(/^data:image\/\w+;base64,/, "");//去掉data:image/png;base64,
      //就是这里需要获取微信环境的保存路径,所以最好把转好的base64传到小程序端来下载    
      let filePath = wx.env.USER_DATA_PATH + '/detail.png';
      uni.getFileSystemManager().writeFile({
        filePath: filePath,  //创建一个临时文件名
        data: base64,    //写入的文本或二进制数据
        encoding: 'base64',  //写入当前文件的字符编码
        success: res => {
          uni.saveImageToPhotosAlbum({
            filePath: filePath,
            success: function (res2) {
              uni.showToast({
                title: '保存成功,请从相册选择再分享',
                icon: "none",
                duration: 5000
              })
            },
            fail: function (err) {
              // console.log(err.errMsg);
            }
          })
        },
        fail: err => {
          //console.log(err)
        }
      })
    },
     //接收来自webview的数据,注意,这里detail.data是一个数组!
     handleMessage(res) {
      this.saveImageToPhotosAlbum(res.detail.data[0].imgData)
     },
    }
  }
</script>
//webview页面端   我用的是html,你也可以用vue,或者其他的什么框架,但是一定要在服务器上。本地的话就开一个nginx服务调试就好。
//这个html是在uniapp webview copy的模板,里面对各种环境都做了处理,所以我们直接在另一个script里面写逻辑就好了。
//引入在线的vue,css,最重要的是这个:https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js ,引入之后允许我们使用uni的部分api。

<!DOCTYPE html>
<html>

<head>
  <meta charset="utf-8" />
  <meta name="viewport" content="width=device-width,initial-scale=1,minimum-scale=1,maximum-scale=1,user-scalable=no" />
  <title>保存html</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  <script src="https://unpkg.com/http-vue-loader"></script>
  <script src="https://html2canvas.hertzen.com/dist/html2canvas.min.js"></script>
  <script src="https://code.jquery.com/jquery-3.1.1.min.js"></script>
  <link rel="stylesheet" href="//at.alicdn.com/t/c/font_3605152_8p2lf6ioizb.css">
  <style type="text/css">
    
  </style>
</head>

<body>
  <div id="app">
    <div class="main-box" :style="{'--uni':uni, 'background': '#FAFAFA url(' + baseUrl + '/img/chuxian_bg.png) no-repeat', 'background-size': '100%' }">
      <div class="order-num">
        订单编号:{{ dataObj.orderNumber }}
      </div>
      <div class="order-title">
        <h1>车辆出险报告</h1>
        <h3>{{ dataObj.model }}</h3>
      </div>
      <div class="save">
        <button @click="savePicture">保存本页</button>
      </div>
    </div>
    <div id="downimg" v-show="false"></div>
  </div>
  <script type="text/javascript">
    var userAgent = navigator.userAgent;
    if (userAgent.indexOf('AlipayClient') > -1) {
      // 支付宝小程序的 JS-SDK 防止 404 需要动态加载,如果不需要兼容支付宝小程序,则无需引用此 JS 文件。
      document.writeln('<script src="https://appx/web-view.min.js"' + '>' + '<' + '/' + 'script>');
    } else if (/QQ/i.test(userAgent) && /miniProgram/i.test(userAgent)) {
      // QQ 小程序
      document.write(
        '<script type="text/javascript" src="https://qqq.gtimg.cn/miniprogram/webview_jssdk/qqjssdk-1.0.0.js"><\/script>'
      );
    } else if (/miniProgram/i.test(userAgent) && /micromessenger/i.test(userAgent)) {
      // 微信小程序 JS-SDK 如果不需要兼容微信小程序,则无需引用此 JS 文件。
      document.write('<script type="text/javascript" src="https://res.wx.qq.com/open/js/jweixin-1.4.0.js"><\/script>');
    } else if (/toutiaomicroapp/i.test(userAgent)) {
      // 头条小程序 JS-SDK 如果不需要兼容头条小程序,则无需引用此 JS 文件。
      document.write(
        '<script type="text/javascript" src="https://s3.pstatp.com/toutiao/tmajssdk/jssdk-1.0.1.js"><\/script>');
    } else if (/swan/i.test(userAgent)) {
      // 百度小程序 JS-SDK 如果不需要兼容百度小程序,则无需引用此 JS 文件。
      document.write(
        '<script type="text/javascript" src="https://b.bdstatic.com/searchbox/icms/searchbox/js/swan-2.0.18.js"><\/script>'
      );
    } else if (/quickapp/i.test(userAgent)) {
      // quickapp
      document.write('<script type="text/javascript" src="https://quickapp/jssdk.webview.min.js"><\/script>');
    }
  </script>
  <!-- uni 的 SDK -->
  <!-- 需要把 uni.webview.1.5.4.js 下载到自己的服务器 -->
  <script type="text/javascript" src="https://unpkg.com/@dcloudio/uni-webview-js@0.0.3/index.js"></script>
  <script type="text/javascript">
    Vue.use(httpVueLoader)
    new Vue({
      el: '#app',
      data: {
        dataObj: {},
        baseUrl: 'https://xxx:8443',
      },
      created () {
        this.dataObj = JSON.parse(this.getQueryString('data'))
        this.dataObj.result = JSON.parse(this.dataObj.result)
        console.log(document.documentElement.clientWidth)
        this.uni = 750 / document.documentElement.clientWidth
        console.log(this.uni)
      },
      methods: {
        getQueryString (name) {
          var reg = new RegExp("(^|&)" + name + "=([^&]*)(&|$)", "i");
          var r = window.location.search.substr(1).match(reg);
          if (r != null) return decodeURI(r[2]); return null;
        },
        plusXing (str, frontLen, endLen, cha) {
          let len = str.length - frontLen - endLen;
          let xing = "";
          for (let i = 0; i < len; i++) {
            xing += cha;
          }
          return (
            str.substring(0, frontLen) + xing + str.substring(str.length - endLen)
          );
        },
    //这里是重点,获取想要保存的html结构,然后设置相应的样式,
        savePicture () {
          let canvas2 = document.createElement('canvas'), // 创建canvas
            _canvas = document.querySelector('.main-box'), //此处可换body,或div等 我们一般可以放绘制的元素
            w = parseInt(window.getComputedStyle(_canvas).width),
            h = parseInt(window.getComputedStyle(_canvas).height);
          //将canvas画布放大若干倍,然后盛放在较小的容器内,就显得不模糊了
          canvas2.width = w * 2;
          canvas2.height = h * 2;
          canvas2.style.width = w + 'px';
          canvas2.style.height = h + 'px';
          let context = canvas2.getContext('2d'),
            rect = $('.main-box').get(0).getBoundingClientRect(); //获取元素相对于视察的偏移量
          context.scale(2, 2);
          context.translate(-rect.left, -rect.top); //设置context位置,值为相对于视窗的偏移量负值,让图片复位
          html2canvas(document.querySelector('.main-box'), {
            canvas: canvas2,
            useCORS: true, // 允许图片跨域
            width: 584,  // 绘制图片的宽 2倍
            dpi: window.devicePixelRatio * 2, // dpi  如果模糊的话 就把dpi和scale缩放的值调大 dpi越高生成的图片越大
            height: 1188 // 绘制图片的高 2倍
          }).then(function (canvas) {
            var url = canvas.toDataURL()     //把canvas转成base64
             uni.postMessage({
              data: {
                imgData: base64, // 刚才拿到的base64 数据
              },
            });
          });
        }
      },
    })

  </script>
</body>

</html>
  • 2
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值