uniapp中生成海报,直接把页面截图保存到手机
在项目中有一个分享二维码的功能,用户生成一个二维码,然后截图保存分享出去。本来智商正常的人都知道怎么截图吧,但是客户说太复杂了,总有些笨蛋不会,要直接点一下就能保存到相册。
那怎么说呢?客户是上帝,客户是衣食父母,来想办法解决一下吧。
对于一个php程序员来说,前端毕竟不够专业,首先想到的就是百度一下,看了一下基本上都是利用canvas画图,矩阵,啥啥啥的,看到头都大,有没有什么办法可以直接把页面截图保存下来呢?
因为之前在h5端做过,
<script src="https://cdn.bootcss.com/html2canvas/0.5.0-beta4/html2canvas.js"></script>
当时用到了
html2canvas
这个插件,那么对于功能更高级的uniapp没道理不能实现吧?
直接上代码吧
<template> <view> <view @click="capture()"> <view class="qrcode"> <image v-if="img" style="width: 200px;height: 200px;" :src="img" mode="scaleToFill"></image> <uqrcode v-else style="display: flex;justify-content: center;align-items: center;" ref="uqrcode"> </uqrcode> <view style="margin-top: 20rpx;">微信扫二维码在浏览器打开</view> </view> <image :src="$request.config.qiniu.share_img" mode="scaleToFill" class="bg"> </image> </view> </view> </template> <script> export default { data() { return { is: true, img: '', $request: this.$request } }, onReady() { this.$refs.uqrcode.make({ size: 200, text: this.$request.baseUrl + "i?id=" + this.$request.uid }) .then(res => { // 返回的res与uni.canvasToTempFilePath返回一致 console.log(res) this.img = res.tempFilePath }) }, methods: { capture() { this.$nextTick(function() { var pages = getCurrentPages(); //获取当前页面信息 console.log(pages); var page = pages[pages.length - 1]; var bitmap = null; var currentWebview = page.$getAppWebview(); bitmap = new plus.nativeObj.Bitmap('amway_img'); let t = this currentWebview.draw(bitmap, function() { let rand = Math.floor(Math.random() * 10000) let saveUrl = '_doc/' + rand + 'a.jpg' bitmap.save(saveUrl, {}, function(i) { uni.showModal({ title: "是否保存图片到手机?", success: (confirm) => { if (confirm.confirm) { uni.saveImageToPhotosAlbum({ filePath: i.target, success: function() { bitmap .clear(); //销毁Bitmap图片 uni.showToast({ title: '保存图片成功', mask: false, duration: 1500 }); } }); } else { bitmap.clear(); //销毁Bitmap图片 } } }) }, function(e) { t.showToast("保存图片失败") }); }, function(e) { t.showToast("截屏绘制图片失败") }); }) }, } } </script> <style scoped> .qrcode { width: 100%; /* height: 260px; */ position: absolute; top: 30%; display: flex; justify-content: center; align-items: center; flex-direction: column; } .bg { position: fixed; width: 100%; height: 100%; top: 0; left: 0; z-index: -1; } </style>
分析一下代码,这里我们用到了一个生成二维码的插件,这类插件很多我们就不具体分析了,主要分析保存页面为图片并保存到相册的功能
capture() { this.$nextTick(function() { var pages = getCurrentPages(); //获取当前页面信息 console.log(pages); var page = pages[pages.length - 1]; var bitmap = null; var currentWebview = page.$getAppWebview(); bitmap = new plus.nativeObj.Bitmap('amway_img'); let t = this currentWebview.draw(bitmap, function() { let rand = Math.floor(Math.random() * 10000) let saveUrl = '_doc/' + rand + 'a.jpg' bitmap.save(saveUrl, {}, function(i) { uni.showModal({ title: "是否保存图片到手机?", success: (confirm) => { if (confirm.confirm) { uni.saveImageToPhotosAlbum({ filePath: i.target, success: function() { bitmap .clear(); //销毁Bitmap图片 uni.showToast({ title: '保存图片成功', mask: false, duration: 1500 }); } }); } else { bitmap.clear(); //销毁Bitmap图片 } } }) }, function(e) { t.showToast("保存图片失败") }); }, function(e) { t.showToast("截屏绘制图片失败") }); }) },
主要用到的就是plus.nativeObj.Bitmap的原生功能。
这里有一个坑我得说一下,注意看
<image v-if="img" style="width: 200px;height: 200px;" :src="img" mode="scaleToFill"></image> <uqrcode v-else style="display: flex;justify-content: center;align-items: center;" ref="uqrcode"> </uqrcode>
我这里用到了一个v-if="img"
为什么,因为这个二维码是通过canvas画出来的,在测试中发现,ios中可以被保存到相册,在安卓中就是,页面中的其他内容都被截图下来了,但是二维码不见了。。。。。
奇了个怪了,那就应该是在安卓中的plus.nativeObj.Bitmap 不支持截图canvas画出来的东西,那么就想一个办法,我生成的二维码不是还有一个Base64格式吗?
那么我生成出来了base64然后再给img填充一下不就行了,试了一下果然可以。
虽然那个二维码会闪一下,不过不影响了。
