介绍
基于Taro,最近写了一个小程序,其中有个小功能是根据后端提供的一个Url,生成一个二维码图片。后这个图片长按,弹出按钮列表,点击【保存到本地】,则能够保存二维码图片到本地相册。
问题抛出
测试反馈,点击【保存到本地】后,提示保存成功,实际手机相册中图片不存在。
问题初步分析
涉及图片保存的地方有多处,有些地方成功,有些地方不成功。带着疑惑分析问题发现:
成功的地方,img 绑定的src 指向的内容,都是图片格式的Url。
而失败的地方,指向的是一个base64格式的字符串,且格式为:data:image/svg+xml;base64
问题判定:微信小程序,应该无法识别该格式内容。
解决问题
-
处理依据
基于目前该功能只在微信小程序中使用,所以查询【weapp-qrcode】相关的npm库。找了一个最近上架的工具:weapp-qrcode-canvas-2d(其他的都太老了)
-
初始代码
根据readme,编写代码如下:
<script setup lang="ts">
import { reactive, onMounted } from 'vue';
import Taro from '@tarojs/taro';
import drawQrcode from 'weapp-qrcode-canvas-2d';
const props = defineProps<Props>();
type Props = {
url: string;
width: number;
height: number;
};
const refData = reactive({
qrCodeURL: ''
});
onMounted(() => {
const query = Taro.createSelectorQuery();
query
.select('#myQrcode')
.fields({
node: true,
size: true
})
.exec(res => {
const canvas = res[0].node;
// 调用方法drawQrcode生成二维码
drawQrcode({
canvas,
canvasId: 'myQrcode',
width: props.width,
height: props.height,
background: '#ffffff',
foreground: '#000000',
text: props.url
});
// 获取临时路径(得到之后,想干嘛就干嘛了)
Taro.canvasToTempFilePath({
canvasId: 'myQrcode',
canvas,
x: 0,
y: 0,
width: props.width,
height: props.height,
destWidth: 600,
destHeight: 600,
success(res) {
refData.qrCodeURL = res.tempFilePath;
console.log('二维码临时路径:', res.tempFilePath);
},
fail(res) {
console.error(res);
}
});
});
});
</script>
<template>
<div>
<canvas
id="myQrcode"
type="2d"
v-show="false"
:style="{ width: `${props.width}px`, height: `${props.height}px` }"
></canvas>
<img
v-if="refData.qrCodeURL"
:src="refData.qrCodeURL"
:style="{ width: `${props.width}px`, height: `${props.height}px` }"
alt="QR Code"
:show-menu-by-longpress="true"
/>
<view class="h-[35px]"></view>
</div>
</template>
<style></style>
上述代码,在微信开发工具中和Android手机上都是能够正常运行的。但是在IOS手机上,二维码是看不见的。
难受了,这是为啥?
-
问题分享并百度
说是v-show=false这个导致,在IOS上拿不到画布对象了。所以就变向救国了,修改代码如下:
<canvas id="myQrcode" type="2d"
:style="{ width: `${props.width}px`, height: `${props.height}px`, left: '9000px', position: 'fixed' }">
</canvas>
在百度的过程中,说微信小程序不支持啥2d格式的canvas等问题,存在误导。只要把canvas移出屏幕可视范围就可以了。
过程总结
业务:先从后端获取一个Url,然后把这个Url显示成二维码图片,然后点击图片能够存储本地相册。
技术:使用weapp-qrcode-canvas-2d完成Url显示成二维码图片;image添加show-menu-by-longpress属性,完成长按保存本地。
问题处理:通过分析和百度,找到使用过程中的问题。
为啥题目是保存、分享等功能呢?因为只要能保存了,那么就能够分享,因为调用的是show-menu-by-longpress属性自带的功能。