需求背景

因微信小程序暂不支持一键分享到朋友圈功能,故要生成图片并保存到手机相册就有两种情况:

1.需保存的图片为静态固定图片。这种情况图片可直接由后端返回,再调用小程序相应api直接保存到手机相册;

2.需保存的图片为动态生成图片(比如,该图片上的用户头像、昵称、根据特有标志生成的小程序码等),此时有两种可行方案,

一是让后端动态生成图片返给前端,再由前端保存;二是前端自己绘制图片并保存。绘制图片对于前后端来说都会消耗一定时间,但考虑到

大量用户同时发起该请求时,会降低服务器性能,故最终采用第二种方案。

canvas绘图实现步骤

1.首先在wxml文件里引入<canvas>组件,并自定义所需长宽,同时给一个id

示例如下:

2.在对应js文件绘制我们所需的图片

drawImage() { // canvas绘制函数
const { drawInfo } = this.data;
const ctx = wx.createCanvasContext('sharePic');
// 背景
ctx.setFillStyle('#fff');
ctx.fillRect(0, 0, rpx2px(409), rpx2px(560));
if (drawInfo) {  // 将下载好的图片按需按序排列,之所以要重新排列,是因为图片是异步下载,其顺序可能与我们期望的有偏差
const { imgArr } = this.data;
const imgArrSort = [];
for (let i = 0; i < imgArr.length; i += 1) {
imgArrSort[imgArr[i].key] = imgArr[i].url;
}
// ctx.save(); // 保存当前画布内容
// 用户头像
// ctx.strokeStyle = '#fff';
// ctx.lineWidth = rpx2px(2);
// ctx.beginPath();
// ctx.arc(rpx2px(83), rpx2px(60), rpx2px(30), 0, 2 * Math.PI);
// ctx.closePath();
// ctx.stroke();
// ctx.clip();
// ctx.drawImage(
// imgArrSort[0],
// rpx2px(53),
// rpx2px(30),
// rpx2px(60),
// rpx2px(60)
// );
// ctx.restore(); // 恢复当前画布内容
// 昵称
ctx.setFillStyle('#000');
ctx.setTextAlign('center');
ctx.setFontSize(rpx2px(16));
ctx.fillText(drawInfo.nickname, rpx2px(204), rpx2px(59));
// 图片标题
ctx.setFillStyle('#fe4070'); // 文字颜色:黑色
ctx.setFontSize(rpx2px(26));
ctx.fillText(drawInfo.share_title, rpx2px(204), rpx2px(127));
// 图片
ctx.drawImage(
imgArrSort[0],
rpx2px(53),
rpx2px(154),
rpx2px(302),
rpx2px(201)
);
// 小程序码
const qrImgSize = rpx2px(140);
ctx.drawImage(
imgArrSort[1],
rpx2px(56),
rpx2px(377),
qrImgSize,
qrImgSize
);
// 小程序码文字说明
ctx.setFillStyle('#333');
ctx.setTextAlign('left');
ctx.setFontSize(rpx2px(17));
ctx.fillText('长按识别小程序码', rpx2px(213), rpx2px(435));
ctx.draw();
} else {
// 获取绘制信息失败
// 图片加载失败提示文案
ctx.setFillStyle('#999'); // 文字颜色:黑色
ctx.setFontSize(rpx2px(22));
ctx.fillText('图片加载失败', rpx2px(140), rpx2px(280));
ctx.setFillStyle('#fff');
ctx.draw();
}
},
downLoadImg(imgList) { //图片下载函数,之所以要先将其下载,是因为如果图片较大或其下载完成速度<canvas绘制速度,图片处会是空白
const that = this;
for (let i = 0; i < imgList.length; i += 1) {
wx.downloadFile({
url: imgList[i],
success: res => {
const { imgArr } = that.data;
imgArr.push({ key: i, url: res.tempFilePath });
that.setData({
imgArr
});
 }
});
}
}
 
3.保存canvas绘制图片到相册
saveImage() {
wx.canvasToTempFilePath({
canvasId: 'sharePic',
success(res) {
wx.saveImageToPhotosAlbum({
filePath: res.tempFilePath,
success() {
wx.showToast({
title: '图片已保存至相册'
});
   }
});
   }
});
}
 
值得思考的几个问题:
 

微信小程序cavas画图并保存的更多相关文章

  1. 微信小程序开发3之保存数据及页面跳转

    第一  保存本地数据 1.异步保存本地数据 wx.setStorage({ key:keyStr, data:dataStr, success: function(e){}, fail: functi ...

  2. 微信小程序看上去很美

    目前不少关于 微信小程序 的文章主要集中在两各方面:一是开发技术细节:二是怎么靠此赚钱. -- “微信小程序”所处的环境 -- 2016年初,美国号召全民学编程,包括监狱服刑人员.同样,在中国要想掌握 ...

  3. 微信小程序动态生成保存二维码

    起源:最近小程序需要涉及到一些推广方面的功能,所以要写一个动态生成二维码用户进行下载分享,写完之后受益良多,特此来分享一下: 一.微信小程序动态生成保存二维码 wxml: <view class ...

  4. 微信小程序 获取用户信息并保存登录状态

    微信小程序 获取用户信息并保存登录状态:http://www.360doc.com/content/18/0124/11/9200790_724662071.shtml

  5. 微信小程序之base64图片如何预览与一键保存到本地相册?

    需求:由于后台服务器各方面的限制,现在服务器返回的图片是base64格式的,小程序端需要支持预览图片和多个图片一键下载功能 一.如何预览base64位图片? WXML页面:item.src的值是bas ...

  6. 微信小程序图片保存到本地

    微信小程序图片保存到本地是一个常用功能: 这里讲解下完整实现思路: 因为微信官方的授权只弹一次,用户拒绝后再次调用,就需要结合button组件的微信开放能力来调起,以下方案在微信各种授权中可参考. w ...

  7. Spring Boot+微信小程序_保存微信登录者的个人信息

    1. 前言 微信小程序开发平台,提供有一类 API,可以让开发者获取到微信登录用户的个人数据.这类 API 统称为开放接口. Tip:微信小程序开发平台,会把微信登录用户的个人信息分为明文数据和敏感数 ...

  8. 小程序canvas生成海报保存至手机相册

    小程序canvas画图保存至手机相册 (1)可直接展示生成的海报 .因手机分辨率不同可能导致生成的海报会有细微差别,这里隐藏canvas海报,页面正常设置海报样式保存时保存隐藏的canvas海报 (2 ...

  9. 利用机器学习实现微信小程序-加减大师自动答题

    之前有看到微信小程序<跳一跳>别人用python实现自动运行,后来看到别人用hash码实现<加减大师>的自动答题领取娃娃,最近一直在研究深度学习,为啥不用机器学习实现呢?不就是 ...

随机推荐

  1. C++11多线程のfuture,promise,package_task

    一.c++11中可以在调用进程中获取被调进程中的结果,具体用法如下 // threadTest.cpp: 定义控制台应用程序的入口点. // #include "stdafx.h" ...

  2. springmvc 自定义拦截器实现未登录用户的拦截

    第一步:编写自定义拦截器类,该类继承HandlerInterceptorAdapter,重写preHandle方法  第二步:配置springmvc.xml文件,定义拦截器属性  登录请求的mappi ...

  3. metamask源码学习-contentscript.js

    When a new site is visited, the WebExtension creates a new ContentScript in that page's context, whi ...

  4. scp传输文件的命令

    scp传输文件的命令 一:scp常规的使用方式: scp可以进行简单的远程复制文件的功能.它是一个在各个主机之间进行复制或文件传输的一个命令工具.它使用一种同ssh一样的安全机制来进行文件的传输. 注 ...

  5. 理解 boxsizing

    理解boxsizing 什么是css盒模型?css盒模型包括如下属性:内容(content),填充(padding),边框(border),边界(margin). 这些东西我们可以拿日常生活中的列子来 ...

  6. 原生js函数的伪重载

    一.我们在学习java的时候,其中方法有一个比较的重要的特性重载,根据传入的参数的个数来执行不同的方法,而方法其根据签名来判断,而JavaScript却不能根据方法的签名来进行重载,只能通过参数的个数 ...

  7. Luogu P2661 [NOIP2015] 信息传递

    qwq 今天做完并查集突然想起来这道以前做的好(shui)题, 虽然是黄题,但是是并查集一个比较特别的用法 这道题大概可以用求最小环的方式来做,但是从直觉上果然还是并查集w 乍一看只要求出“父→子”即 ...

  8. jdk和cglib简单理解

    之前使用cglib的时候不需要将classLoader作为参数传入,但动态代理却要,带着这个疑惑进入这个方法: Proxy.newProxyInstance(classLoader, interfac ...

  9. [06] Bean属性的注入

    之前我们提到了Bean实例化的三种方式:构造器方式.静态工厂方式.普通工厂方式.那么对于Bean中的属性,又是如何进行注入的(依赖注入),这个篇章就来提一提. 1.先提提什么是"依赖注入&q ...

  10. YOU AND ME 不见不散(转载)

    (看到一篇挺不错的文章,看了挺有感触的,与大家共勉.) 泰戈尔说: 有一个夜晚,我烧毁了所有的记忆, 从此我的梦就透明了: 有个早晨我扔掉了所有的昨天, 从此我的脚步就轻盈了! 越过山丘,才发现无人等 ...