微信小程序canvas生成并保存图片,具体实现效果如下图

   

实现效果需要做以下几步工作

一、先获取用户屏幕大小,然后才能根据屏幕大小来定义canvas的大小

二、获取图片(二维码)的宽高,并对图片进行等比例缩放在canvas绘制

三、文字的布局

四、将canvas内容生成图片并保存到本地

五、并图片保存到相册

具体实现代码如下 主逻辑 代码量比较多,分段来展示

/*页面data定义所需参数*/
data{
// canvas
_width: 0, //手机屏宽
_heigth: 0,//手机屏高
swiperHeight: 0,//主图图片高度
canvasType: false//canvas是否显示
loadImagePath: '',//下载的图片
imageUrl: 'http://imgo2o.shikee.com/goods/2019/10/17/201910171144361688.jpg', //主图网络路径
codeUrl: 'http://imgo2o.shikee.com/couponqrcode/2019/10/18/86_215.jpg',//二维码网络路径
localImageUrl: '', //绘制的商品图片本地路径
localCodeUrl: '', //绘制的二维码图片本地路径
loadType: flase //保存图片,分享好友 Btn
}
/* 图片加载时 页面加载主图时触发
<image src="{{item}}" class="img" mode="widthFix" bindload="onSwiperLoad"></image>
*/
onImgLoad: function(e) {
let oImgW = e.detail.width; //图片原始宽度
let oImgH = e.detail.height; //图片原始高度
let imgWidth = 750; //图片设置的宽度
let scale = imgWidth / oImgW; //比例计算
let imgHeight = oImgH * scale; this.setData({
swiperHeight: imgHeight,
})
}
/*按生成图片按钮时*/
getSysInfo: function() {
/*获取手机宽高*/
let that = this
let imgUrl = this.data.imageUrl
let qrcodeUrl = this.data.codeUrl
wx.getSystemInfo({
success(res) {
that.setData({
_width: res.windowWidth,
_heigth: res.windowHeight,
canvasType: true,
})
// 获取图片信息生成canvas
that.getImginfo([imgUrl, qrcodeUrl], 0);
}
})
}
// 获取图片信息
getImginfo: function(urlArr, _type) {
let that = this;
wx.getImageInfo({
src: urlArr[_type], //服务器返回的带参数的小程序码地址
success: function(res) {
//res.path是网络图片的本地地址
if (_type === 0) { //商品图片
that.setData({
localImageUrl: res.path,
})
that.getImginfo(urlArr, 1)
} else {
that.setData({ //二维码
localCodeUrl: res.path,
loadType: true,
})
// 创建canvas图片
that.createNewImg();
}
},
fail: function(res) {
//失败回调
console.log('错误-res', _type, res)
}
});
},
//绘制canvas
createNewImg: function() {
let _width = this.data._width,
_heigth = this.data._heigth; //屏幕宽与高 let imgHeigth = this.data.swiperHeight, //原图片高度
scale = (_width - 40) / _width, //缩小比例
that = this;
let imgH = imgHeigth * scale; //绘制时图片显示高度
let ctx = wx.createCanvasContext('mycanvas');
// 绘制背景
ctx.setFillStyle("#fff");
ctx.fillRect(0, 0, _width - 40, imgH + 160);
//绘制图片
ctx.drawImage(this.data.localImageUrl, 10, 10, _width - 60, imgH); // 绘制标题
ctx.setFontSize(18);
ctx.setFillStyle('#333'); let txtWidth = _width - 60 + 30 - 100 - 50; //文字的宽度 //商品名称 最多两行显示 写法有点LOW,但思路是这样的
let title = this.data.goods.title; //商品名称
let title2; //商品名称
if (title.length > 10) {
title2 = title.slice(10, title.length);
title = title.slice(0, 10);
}
if (title2.length > 10) {
title2 = title2.slice(0, 9) + ' ...';
}
ctx.fillText(title, 10, imgH + 40, txtWidth);
ctx.fillText(title2, 10, imgH + 70, txtWidth);
// 绘制价格 '¥'
ctx.setFontSize(14);
ctx.setFillStyle('#d2aa68');
ctx.fillText('¥', 10, imgH + 110, txtWidth);
// 绘制价格
ctx.setFontSize(24);
ctx.fillText(this.data.goods.promotion_price, 26, imgH + 110, txtWidth);
// 绘制门市价
ctx.setFontSize(14);
ctx.setFillStyle('#666');
ctx.fillText(`门市价¥${this.data.goods.price}`, 115, imgH + 110, txtWidth); // 绘制二维码
ctx.drawImage(this.data.localCodeUrl, _width - 80 + 80 - 150, imgH + 20, 100, 100);
// 显示绘制
ctx.draw(); //将生成好的图片保存到本地,需要延迟一会,绘制期间耗时
setTimeout(function() {
wx.canvasToTempFilePath({
canvasId: 'mycanvas',
success: function(res) {
var tempFilePath = res.tempFilePath;
that.setData({
loadImagePath: tempFilePath,
});
},
fail: function(res) {
console.log(res);
}
});
}, 500);
}
//点击保存到相册
saveImg: function() {
wx.saveImageToPhotosAlbum({
filePath: this.data.loadImagePath,
success(res) {
console.log('res', res);
wx.showToast({
title: '已保存到相册',
icon: 'success',
duration: 3000
})
}
})
}
// 关闭 海报弹窗
closePos: function() {
this.setData({
canvasType: false
});
}

页面代码部分

<view class='poster' wx:if="{{canvasType}}">
<canvas class='canvas' style='height:{{canvasH}}px;width:{{canvasW}}px;' canvas-id="mycanvas" /> <cover-view class='opt' hidden='{{!loadType}}'>
<cover-view class='cont'>
<cover-view class='item' bindtap='saveImg'>
<cover-image class='ico' src='{{server_img_url}}ico/icon_download.png'></cover-image>
<cover-view>保存到相册</cover-view>
</cover-view> </cover-view>
</cover-view>
<cover-view class='btn-box' hidden='{{!loadType}}'>
<button bindtap='closePos' class='btn'>取消</button>
</cover-view>
</view> <view class="btn-box">
<button class='m-btn-share' bindtap='getSysInfo'>生成图片</button>
<button class='m-btn' open-type='share'>call友来抢</button>
</view>

微信小程序canvas生成并保存图片的更多相关文章

  1. 微信小程序 canvas 生成随机验证码

    转载:https://blog.csdn.net/qq_16646819/article/details/81020245?utm_source=blogxgwz0 js // pages/bind/ ...

  2. 微信小程序 canvas 绘图问题总结

    业务中碰到微信小程序需要生成海报进行朋友圈分享,这个是非常常见的功能,没想到实际操作的时候花了整整一天一夜才搞好,微信的 canvas 绘图实在是太难用了,官方快点优化一下吧. 业务非常简单,只需要将 ...

  3. 微信小程序 canvas 字体自动换行(支持换行符)

    微信小程序 canvas 自动适配 自动换行,保存图片分享到朋友圈  https://github.com/richard1015/News 微信IDE演示代码https://developers.w ...

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

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

  5. 原创:WeZRender:微信小程序Canvas增强组件

    WeZRender是一个微信小程序Canvas增强组件,基于HTML5 Canvas类库ZRender. 使用 WXML: <canvas style="width: 375px; h ...

  6. 微信小程序-canvas绘制文字实现自动换行

    在使用微信小程序canvas绘制文字时,时常会遇到这样的问题:因为canvasContext.fillText参数为 我们只能设置文本的最大宽度,这就产生一定的了问题.如果我们绘制的文本长度不确定或者 ...

  7. 微信小程序--canvas画布实现图片的编辑

    技术:微信小程序   概述 上传图片,编辑图片大小,添加文字,改变文字颜色等 详细 代码下载:http://www.demodashi.com/demo/14789.html 概述 微信小程序--ca ...

  8. 微信小程序一键生成源码 在线制作定制功能强大的微信小程序

    微信小程序发展到现在,短短的一年不到的时间(很快就要迎来微信小程序周年庆),在快迎来周年庆之际,百牛信息技术bainiu.ltd特记录一下这个发展的历程,用于将来见证小程序发展的辉煌时刻,我们还能知道 ...

  9. 技术博客--微信小程序canvas实现图片编辑

    技术博客--微信小程序canvas实现图片编辑 我们的这个小程序不仅仅是想给用户提供一个保存和查找的平台,还希望能给用户一个展示自己创意的舞台,因此我们实现了图片的编辑部分.我们对对图片的编辑集成了很 ...

随机推荐

  1. NOIP2002 1.级数求和

    这题目...... 题目:已知:Sn= 1+1/2+1/3+…+1/n.显然对于任意一个整数K,当n足够大的时候,Sn大于K.现给出一个整数K(1<=k<=15),要求计算出一个最小的n: ...

  2. Hessian 接口使用示例总结(转载)

    一.使用hessian接口准备 首先,hessian接口的使用,必须要准备hessian接口的jar包,本文使用的jar包如下:hessian-4.0.7.jar; Hessian接口的使用一般是在两 ...

  3. Flutter 中文文档网站 flutter.cn 正式发布!

    在通常的对 Flutter 介绍中,最耳熟能详的是下面四个特点: 精美 (Beautiful):充分的赋予和发挥设计师的创造力和想象力,让你真正掌控屏幕上的每一个像素. ** 极速 (Fast)**: ...

  4. 即时聊天APP(四) - 联系人和会话

    联系人和会话界面使用的是RecyclerView进行滑动显示,并将好友列表存储至数据库,以供下次登录时使用,RecyclerView在后面我会详细介绍,这里略过. 联系人初始化时读取数据库并展示: / ...

  5. FEDay会后-Serverless与云开发,可能是前端的下一站

    进化本身是生物体与环境之间持续不断的信息交换的具体表现. -- 摘自<信息简史> 很荣幸在9月21号成都举办的第五届FEDay上作为讲师为大家分享腾讯云在近两年推出的云开发相关的技术和知识 ...

  6. Postman工具使用-接口测试(实战一)

    写在前面,本文首发[简书]https://www.jianshu.com/p/c188624c3580 作为一名测试人员,要去思考一下,如何能按需完成任务,又能轻松解决问题,这就很重要了!!! 凡事皆 ...

  7. 指针生产网络(Pointer-Generator-Network)原理与实战

    0 前言 本文内容主要:介绍Pointer-Generator-Network在文本摘要任务中的背景,模型架构与原理.在中英文数据集上实战效果与评估,最后得出结论.参考的<Get To The ...

  8. MySQL性能优化以及常用命令

    1.将查询操作SELECT中WHERE条件后面和排序字段建立索引 2.按需查询,需要哪个字段就查哪个字段,禁止使用"SELECT * " 3.数据库引擎最好选用InnoDB,少用M ...

  9. 初识Hiberante框架和第一个案例

    今天想回顾一下一个月前学的hibernate框架,也让我了解了持久层的概念(访问数据库). 一.ORM概念 首先提的是ORM概念,O表示Object, R表示Relation(关系),关系型数据库,如 ...

  10. JS 取整、取余

    一.取整 1. 取整 // 丢弃小数部分,保留整数部分 parseInt(7/2) // 3 2. 向上取整 // 向上取整,有小数就整数部分加1 Math.ceil(7/2) // 4 3. 向下取 ...