前言

项目中,一个分享的功能,需要实现对用户二维码的图片下载,并且需要带上其他信息。

实现方式

  1. 生成对应的二维码图片,在用canvas按比例重绘一个区域,再转图片base64
  2. 使用a链接加上download属性,实现图片的下载。

<a :href="shareUrl" download="baidu.png" />

遇到的问题

  1. 实际测试中,转后的base64图片在安卓上不支持,文件变.bin或者显示不出来。
  2. 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')
}

结论

  1. h5中,safari 浏览器支持blob,base64图片的下载。
  2. 安卓浏览器不支持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>

 

Logo

华为开发者空间,是为全球开发者打造的专属开发空间,汇聚了华为优质开发资源及工具,致力于让每一位开发者拥有一台云主机,基于华为根生态开发、创新。

更多推荐