图片海报功能实现
前言项目中,一个分享的功能,需要实现对用户二维码的图片下载,并且需要带上其他信息。实现方式生成对应的二维码图片,在用canvas按比例重绘一个区域,再转图片base64。使用a链接加上download属性,实现图片的下载。<a :href="shareUrl" download="baidu.png" />遇到的问题实际测试中,转后的base64图片在安卓上不支持,文件变.bin或者显
·
前言
项目中,一个分享的功能,需要实现对用户二维码的图片下载,并且需要带上其他信息。
实现方式
- 生成对应的二维码图片,在用canvas按比例重绘一个区域,再转图片base64。
- 使用a链接加上download属性,实现图片的下载。
<a :href="shareUrl" download="baidu.png" />
遇到的问题
- 实际测试中,转后的base64图片在安卓上不支持,文件变.bin或者显示不出来。
- 在safari 中,属性download还不能添加.png,会出现重复的.png,重复时候图片也打不开(canvas.toDataURL能转png跟jpeg)。
解决方式
图片转blob文件,可以适用安卓跟safari浏览器,但是安卓端的图片名称没法更改(项目中未找到解决方式)。
以下代码为转blob跟转base64。 以下代码原文地址:https://www.jianshu.com/p/dfe9c351b898
function downloadImgByBlob(url) {
var img = new Image()
img.onload = function() {
var canvas = document.createElement('canvas')
canvas.width = img.width
canvas.height = img.height
var ctx = canvas.getContext('2d')
// 将img中的内容画到画布上
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
// 将画布内容转换为Blob
canvas.toBlob((blob) => {
// blob转为同源url
var blobUrl = window.URL.createObjectURL(blob)
// 创建a链接
var a = document.createElement('a')
a.href = blobUrl
a.download = '' //文件名称,不填默认为当前请求名称
// 触发a链接点击事件,浏览器开始下载文件
a.click()
})
}
img.src = url
// 必须设置,否则canvas中的内容无法转换为blob
img.setAttribute('crossOrigin', 'Anonymous')
}
function downloadImgByBase64(url) {
var img = new Image()
img.onload = function() {
var canvas = document.createElement('canvas')
canvas.width = img.width
canvas.height = img.height
var ctx = canvas.getContext('2d')
// 将img中的内容画到画布上
ctx.drawImage(img, 0, 0, canvas.width, canvas.height)
// 将画布内容转换为base64
var base64 = canvas.toDataURL()
// 创建a链接
var a = document.createElement('a')
a.href = base64
a.download = ''
// 触发a链接点击事件,浏览器开始下载文件
a.click()
}
img.src = url
// 必须设置,否则canvas中的内容无法转换为base64
img.setAttribute('crossOrigin', 'Anonymous')
}
结论
- h5中,safari 浏览器支持blob,base64图片的下载。
- 安卓浏览器不支持base64,但支持blob(在我的项目中,安卓blob图片文件重命名失败)。
以下为项目中,canvas组件实现代码
<template>
<view class="code-canvas"><canvas style="width:300px;height:340px;" canvas-id="homeownerCanvas"></canvas></view>
</template>
<script>
export default {
data() {
return {};
},
props: {
userInfo: [Object, String]
},
methods: {
init(url) {
var ctx = uni.createCanvasContext('homeownerCanvas');
// 画背景
this.backgroundDraw(ctx, url);
// 画二维码图
this.drawCircular(ctx, this.userInfo.userIcon, 20, 30, 50, 50);
ctx.drawImage(url, 55, 100, 190, 190);
ctx.draw();
setTimeout(() => {
var dataURL = document.getElementsByTagName('canvas')[1].toDataURL('image/jpg');
this.$emit('setDownUrl', dataURL);
}, 1000);
},
async getImageInfo({ imgSrc }) {
return new Promise((resolve, errs) => {
uni.getImageInfo({
src: imgSrc,
success: function(image) {
resolve(image);
},
fail(err) {
errs(err);
}
});
});
},
// 画背景
backgroundDraw(ctx, url) {
// 开始一个新路径
ctx.beginPath();
let x0 = 0,
y0 = 0;
// 移动到中心点
ctx.moveTo(x0, y0);
// 背景的长
ctx.fillStyle = '#fff';
ctx.rect(x0, y0, 300, 340);
ctx.fillStyle = '#fff';
// 填充
ctx.fill();
// 设置字体
ctx.font = '12px bold 黑体';
// 设置颜色
ctx.fillStyle = '#666666';
// 设置水平对齐方式
ctx.textAlign = 'center';
// 设置垂直对齐方式
ctx.textBaseline = 'middle';
// 绘制文字(参数:要写的字,x坐标,y坐标)
ctx.fillText('扫一扫上面的二维码图案,加我为好友', 150, 320);
ctx.fillText('关注:' + this.userInfo.focusNum, 100, 70);
ctx.fillText('粉丝:' + this.userInfo.fans, 160, 70);
ctx.font = '16px bold 黑体';
ctx.fillStyle = '#000';
ctx.fillText(this.userInfo.userName, 136, 45);
ctx.stroke();
},
drawCircular(ctx, url, x, y, width, height) {
//画圆形头像
var avatarurl_width = width;
var avatarurl_heigth = height;
var avatarurl_x = x;
var avatarurl_y = y;
ctx.save();
ctx.beginPath();
ctx.arc(avatarurl_width / 2 + avatarurl_x, avatarurl_heigth / 2 + avatarurl_y, avatarurl_width / 2, 0, Math.PI * 2, false);
ctx.clip();
ctx.drawImage(url, avatarurl_x, avatarurl_y, avatarurl_width, avatarurl_heigth);
ctx.restore();
}
}
};
</script>
<style lang="scss" scope></style>
更多推荐
已为社区贡献1条内容
所有评论(0)