微信小程序-CANVAS写入图片素材、文字等数据生成图片

微信小程序中,CANVAS写入图片素材、文字等数据生成图片,最终可将生成的 base64 格式图片保存至相册操作

Tips:

1、canvas 标签默认宽度 300px、高度 150px
canvas 生成图片时,写入图片素材、文字等数据前,需要根据实际需求,设置 canvas 宽、高,
如以下示例中 设置 posterCanvas.width 及 posterCanvas.height

2、同一页面中的 canvas-id 不可重复,如果使用一个已经出现过的 canvas-id,该 canvas 标签对应的画布将被隐藏并不再正常工作
canvas 不可设置隐藏,否则不能正常工作,若不希望其显示的话,可以 如以下示例中 设置 CSS样式,
makeResCanvasW 、 makeResCanvasH 都设置为 0 ,
- 原生开发:
style="width: {{makeResCanvasW}}rpx;height: {{makeResCanvasH}}rpx;"

- uniapp开发:
:style="'width: ' + makeResCanvasW + 'rpx;height: ' + makeResCanvasH + 'rpx;'"

3、多次生成操作时,清除之前写入数据即可,不需要设置多个 canvas
如以下示例中 setCanvasCtx 方法设置
判断是否已有 Canvas 对象,无则设置 Canvas 对象 及 Canvas 绘制上下文 ctx,有则清除之前写入的数据

4、写入图片素材、文字等数据,与普通H5操作一致
写入图片设置:
注:使用网络图片时,使用 downloadFile 方法,下载文件资源到本地进行处理(返回文件的本地临时路径 (本地路径),单次下载允许的最大文件为 200MB)
如以下示例中 步骤:
- posterCanvas.createImage() 创建一个图片对象
- .src 设置图片的 URL
- .onload 图片加载完成后触发的回调函数,这里可以获取到此图片对象的宽高等数据
- .drawImage 画入图片数据
- 其他写入数据:与H5中处理基本一致

5、生成图片(base64 格式图片)
如以下示例中 posterCanvas.toDataURL('image/png') ,生成图片后,可使用 小程序预览图片方法 previewImage 方法查看生成的图片

6、base64 格式图片保存至相册
如以下示例中 base64ImageHandle 方法设置,
步骤:
- .env.USER_DATA_PATH : 指定图片的临时路径【.env 环境变量 .USER_DATA_PATH 文件系统中的用户目录路径 (本地路径)】
- getFileSystemManager : 获取小程序的文件系统(小程序获取全局唯一的文件管理器方法)
- .writeFile : 把arraybuffer数据写入到临时目录中(写文件)
- 使用小程序保存图片到系统相册方法 saveImageToPhotosAlbum,把临时路径下的图片,保存图片到相册

微信小程序-原生开发,处理代码如下:

wxml:

<canvas type="2d" id="makeResCanvas" style="width: {{makeResCanvasW}}rpx;height: {{makeResCanvasH}}rpx;"></canvas>

data中参数:

data: {makeResCanvasW : 0,makeResCanvasH : 0,
},

调用方法生成图片

this.makeResImg();

处理方法:

/*** CANVAS画布生成图片*/
makeResImg() {wx.showLoading({title: "生成中",mask: true});this.setCanvasCtx(()=>{this.makeResImgAfter();})
},
// 
setCanvasCtx(callback){if(this.data.posterCanvas){console.log(222)this.data.posterCtx.clearRect(0, 0, this.data.posterCanvas.width, this.data.posterCanvas.height);callback && callback();}else{console.log(111)const query = wx.createSelectorQuery();query.select('#makeResCanvas').fields({node: true,size: true}).exec((res) => {// console.log(res);this.setData({posterCanvas : res[0].node})this.setData({posterCtx : this.data.posterCanvas.getContext('2d')})this.data.posterCtx.clearRect(0, 0, this.data.posterCanvas.width, this.data.posterCanvas.height);callback && callback();})}
},
// 
makeResImgAfter(){// 写入 生成图片 背景图片const posterBgImg = this.data.posterCanvas.createImage();posterBgImg.src = '../../images/poster_bg.png';// this.getDownloadFile('https://xxxxxxxxx/poster_bg.png',(formimgTempFilePath)=>{// posterBgImg.src = formimgTempFilePath;posterBgImg.onload = () => {console.log('背景图实际宽高', posterBgImg.width, posterBgImg.height);this.data.posterCanvas.width = posterBgImg.width;this.data.posterCanvas.height = posterBgImg.height;this.setData({makeResCanvasW:0,makeResCanvasH:0,})// 画入背景图片this.data.posterCtx.drawImage(posterBgImg, 0, 0, posterBgImg.width, posterBgImg.height);// 写入 生成图片 勾选标识图片const checkImg = this.data.posterCanvas.createImage();checkImg.src = '../../images/check.png';// this.getDownloadFile('https://xxxxxxxxx/check.png',(checkTempFilePath)=>{// checkImg.src = checkTempFilePath;checkImg.onload = () => {// 画入勾选标识图片this.data.posterCtx.drawImage(checkImg, 20, 188, 32, 24);this.data.posterCtx.drawImage(checkImg, 20 + 42, 188, 32, 24);this.data.posterCtx.drawImage(checkImg, 20 + 42 + 42, 188, 32, 24);this.data.posterCtx.drawImage(checkImg, 20 + 42 + 42 + 42, 188, 32, 24);this.data.posterCtx.drawImage(checkImg, 20 + 42 + 42 + 42 + 42, 188, 32, 24);this.data.posterCtx.drawImage(checkImg, 20 + 42 + 42 + 42 + 42 + 42, 188, 32, 24);// 写入文本this.data.posterCtx.fillStyle = '#000000';this.data.posterCtx.textAlign = 'left';this.data.posterCtx.textBaseline = 'top';this.data.posterCtx.font = '26px "PingFangSC-Regular","STHeitiSC-Light","微软雅黑","Microsoft YaHei","sans-serif"';// 写入单行文本this.data.posterCtx.fillText('写入单行文本',10,60);// 写入多行文本this.writeTextOnCanvas(this.data.posterCtx, 36, 40, '写入多行文本写入多行文本写入多行文本写入多行文本写入多行文本写入多行文本' ,10, 100);// 生成图片this.setData({posterUrl: this.data.posterCanvas.toDataURL('image/png'),})// 查看生成的图片setTimeout(()=>{wx.previewImage({current: this.data.posterUrl,urls: [this.data.posterUrl]});},10)wx.hideLoading();// base64图片保存至相册setTimeout(()=>{this.base64ImageHandle(this.data.posterUrl);},10)}// })}// })
},
// 写入多行文本
writeTextOnCanvas(ctx_2d, lineheight, bytelength, text ,startleft, starttop){function getTrueLength(str){var len = str.length, truelen = 0;for(var x = 0; x < len; x++){if(str.charCodeAt(x) > 128){truelen += 2;}else{truelen += 1;}}return truelen;}function cutString(str, leng){var len = str.length, tlen = len, nlen = 0;for(var x = 0; x < len; x++){if(str.charCodeAt(x) > 128){if(nlen + 2 < leng){nlen += 2;}else{tlen = x;break;}}else{if(nlen + 1 < leng){nlen += 1;}else{tlen = x;break;}}}return tlen;}for(var i = 1; getTrueLength(text) > 0; i++){var tl = cutString(text, bytelength);ctx_2d.fillText(text.substr(0, tl).replace(/^\s+|\s+$/, ""), startleft, (i-1) * lineheight + starttop);text = text.substr(tl);}
},
// 下载网络图片
getDownloadFile(img,callback){wx.downloadFile({url: img,success (res) {if (res.statusCode === 200) {callback && callback(res.tempFilePath)}}})
},
// base64图片保存至相册
base64ImageHandle(base64) {// 指定图片的临时路径const path = `${wx.env.USER_DATA_PATH}/reportformImg.png`// 获取小程序的文件系统const fsm = wx.getFileSystemManager()// 把arraybuffer数据写入到临时目录中fsm.writeFile({filePath: path,data: base64.replace(/^data:image\/\w+;base64,/, ''),encoding: 'base64',success: () => {wx.hideLoading();wx.showModal({title: '保存图片',content: '保存数据报表图片至手机相册?',success: (result) => {if (result.confirm) {// 把临时路径下的图片,保存至相册wx.saveImageToPhotosAlbum({filePath: path,success: () => {wx.showToast({title: '保存海报成功',icon: 'success',duration: 2000})}})}}})}})
},

微信小程序-uniapp开发,处理代码如下:

.vue:

<canvas type="2d" id="makeResCanvas" :style="'width: ' + makeResCanvasW + 'rpx;height: ' + makeResCanvasH + 'rpx;'"></canvas>

data中参数:

data() {return {makeResCanvasW:0,makeResCanvasH:0,};
},

调用方法生成图片

this.makeResImg();

处理方法:

/*** CANVAS画布生成图片*/
makeResImg() {uni.showLoading({title: "生成中",mask: true});this.setCanvasCtx(()=>{this.makeResImgAfter();})
},
// 
setCanvasCtx(callback){if(this.posterCanvas){console.log(222)this.posterCtx.clearRect(0, 0, this.posterCanvas.width, this.posterCanvas.height);callback && callback();}else{console.log(111)const query = uni.createSelectorQuery();query.select('#makeResCanvas').fields({node: true,size: true}).exec((res) => {// console.log(res);this.posterCanvas = res[0].node;this.posterCtx = this.posterCanvas.getContext('2d');this.posterCtx.clearRect(0, 0, this.posterCanvas.width, this.posterCanvas.height);callback && callback();})}
},
// 
makeResImgAfter(){// 写入 生成图片 背景图片const posterBgImg = this.posterCanvas.createImage();posterBgImg.src = '/static/images/xjshop/poster_bg.png';// this.getDownloadFile('https://xxxxxxxxx/poster_bg.png',(formimgTempFilePath)=>{// posterBgImg.src = formimgTempFilePath;posterBgImg.onload = () => {// console.log('背景图实际宽高', posterBgImg.width, posterBgImg.height);this.posterCanvas.width = posterBgImg.width;this.posterCanvas.height = posterBgImg.height;this.makeResCanvasW = 0;this.makeResCanvasH = 0;// 画入背景图片this.posterCtx.drawImage(posterBgImg, 0, 0, posterBgImg.width, posterBgImg.height);// 写入 生成图片 勾选标识图片const checkImg = this.posterCanvas.createImage();// checkImg.src = '/static/images/xjshop/check.png';this.getDownloadFile('https://xxxxxxxxx/check.png',(checkTempFilePath)=>{checkImg.src = checkTempFilePath;checkImg.onload = () => {// 画入勾选标识图片this.posterCtx.drawImage(checkImg, 20, 188, 32, 24);this.posterCtx.drawImage(checkImg, 20 + 42, 188, 32, 24);this.posterCtx.drawImage(checkImg, 20 + 42 + 42, 188, 32, 24);this.posterCtx.drawImage(checkImg, 20 + 42 + 42 + 42, 188, 32, 24);this.posterCtx.drawImage(checkImg, 20 + 42 + 42 + 42 + 42, 188, 32, 24);this.posterCtx.drawImage(checkImg, 20 + 42 + 42 + 42 + 42 + 42, 188, 32, 24);// 写入文本this.posterCtx.fillStyle = '#000000';this.posterCtx.textAlign = 'left';this.posterCtx.textBaseline = 'top';this.posterCtx.font = '26px "PingFangSC-Regular","STHeitiSC-Light","微软雅黑","Microsoft YaHei","sans-serif"';// 写入单行文本this.posterCtx.fillText('写入单行文本',10,60);// 写入多行文本this.writeTextOnCanvas(this.posterCtx, 36, 40, '写入多行文本写入多行文本写入多行文本写入多行文本写入多行文本写入多行文本' ,10, 100);// 生成图片this.posterUrl = this.posterCanvas.toDataURL('image/png')// 查看生成的图片setTimeout(()=>{uni.previewImage({current: this.posterUrl,urls: [this.posterUrl]});},10)uni.hideLoading();// base64图片保存至相册setTimeout(()=>{this.base64ImageHandle(this.posterUrl);},10)}})}// })
},
// 写入多行文本
writeTextOnCanvas(ctx_2d, lineheight, bytelength, text ,startleft, starttop){function getTrueLength(str){var len = str.length, truelen = 0;for(var x = 0; x < len; x++){if(str.charCodeAt(x) > 128){truelen += 2;}else{truelen += 1;}}return truelen;}function cutString(str, leng){var len = str.length, tlen = len, nlen = 0;for(var x = 0; x < len; x++){if(str.charCodeAt(x) > 128){if(nlen + 2 < leng){nlen += 2;}else{tlen = x;break;}}else{if(nlen + 1 < leng){nlen += 1;}else{tlen = x;break;}}}return tlen;}for(var i = 1; getTrueLength(text) > 0; i++){var tl = cutString(text, bytelength);ctx_2d.fillText(text.substr(0, tl).replace(/^\s+|\s+$/, ""), startleft, (i-1) * lineheight + starttop);text = text.substr(tl);}
},
// 下载网络图片
getDownloadFile(img,callback){uni.downloadFile({url: img,success (res) {if (res.statusCode === 200) {callback && callback(res.tempFilePath)}}})
},
// base64图片保存至相册
base64ImageHandle(base64) {// 指定图片的临时路径const path = `${uni.env.USER_DATA_PATH}/reportformImg.png`// 获取小程序的文件系统const fsm = uni.getFileSystemManager()// 把arraybuffer数据写入到临时目录中fsm.writeFile({filePath: path,data: base64.replace(/^data:image\/\w+;base64,/, ''),encoding: 'base64',success: () => {uni.hideLoading();uni.showModal({title: '保存图片',content: '保存数据报表图片至手机相册?',success: (result) => {if (result.confirm) {// 把临时路径下的图片,保存至相册uni.saveImageToPhotosAlbum({filePath: path,success: () => {uni.showToast({title: '保存海报成功',icon: 'success',duration: 2000})}})}}})}})
},

素材图片

原生开发 生成图片

uniapp开发 生成图片

 下载图片提示

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/49514.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

叶再豪降龙精英课程总结

文章目录 1.思维认知1.1 稻盛和夫成功公式1.2 龙头主升模式1.3 龙头主升-两种路径1.4 股市新手的炒股思路1.5 龙头案例1.6 降龙心法 2.情绪周期2.1 情绪周期2.1 情绪演绎周期2.2 情绪的四个部分2.2.1 指数的情绪周期2.2.3 热点情绪周期2.2.4 热点情绪演绎周期2.2.5 大热点支线2…

深入了解路由器工作原理:从零开始的简单讲解

简介 在现代网络中&#xff0c;路由器扮演着至关重要的角色。它不仅连接了不同的设备&#xff0c;还确保数据能够准确地传输到目的地。本文将带你深入探讨路由器的工作原理&#xff0c;帮助网络基础小白们理解这一重要设备的基本功能。 路由器的构成 路由器是一种具有多个输入…

纷享AI | AI技术在销售场景的应用与实践

AI高速发展的今天&#xff0c;各行业都经历着深刻变革。但机遇与挑战总相伴相生&#xff0c;各企业负责人事实上也正面临着如何有效利用AI以完成赋能销售业务的难题。 毋庸置疑&#xff0c;跟上技术潮流&#xff0c;通过落实AI在销售场景中的应用进而取得卓越赋能成果必然是行…

Android TabLayout的简单用法

TabLayout 注意这里添加tab&#xff0c;使用binding.tabLayout.newTab()进行创建 private fun initTabs() {val tab binding.tabLayout.newTab()tab.text "模板库"binding.tabLayout.addTab(tab)binding.tabLayout.addOnTabSelectedListener(object : TabLayout.On…

深度学习系列一

激活函数 sigmod 梯度消失问题&#xff1a; sigmoid函数的导数在输入值较大或较小时接近于0。在反向传播过程中&#xff0c;这些小梯度会相乘&#xff0c;导致深层网络的梯度变得非常小。结果是&#xff0c;深层网络的参数几乎不会更新&#xff0c;训练变得非常困难。这就是为…

Passing output of 3DCNN layer to LSTM layer

题意&#xff1a;将3DCNN&#xff08;三维卷积神经网络&#xff09;层的输出传递给LSTM&#xff08;长短期记忆网络&#xff09;层 问题背景&#xff1a; Whilst trying to learn Recurrent Neural Networks(RNNs) am trying to train an Automatic Lip Reading Model using 3…

2024年上半年主要游戏安全风险,该如何应对?

随着游戏行业的蓬勃发展&#xff0c;安全问题也日益成为行业关注的焦点。面对 2024 年上半 年的游戏安全风险挑战&#xff0c;游戏行业需要不断加强技术能力&#xff0c;完善安全策略&#xff0c;与各方共 同努力&#xff0c;打造一个更加安全、公平的游戏环境。 游戏安全解…

前端程序员会演化出类TA岗位吗?

前端开发领域确实在不断演化&#xff0c;随着技术的进步和行业的需求变化&#xff0c;前端程序员的角色和职责也在拓展&#xff0c;这自然催生了一系列相关的专业岗位。以下是一些从前端开发领域分化出来的专业角色&#xff0c;我们可以称之为“类TA”&#xff08;Technical Ad…

BGP之选路MED

原理概述 当一台BGP路由器中存在多条去往同一目标网络的BGP路由时&#xff0c;BGP协议会对这些BGP路由的属性进行比较&#xff0c;以确定去往该目标网络的最优BGP路由。BGP路由属性的比较顺序为Preferred Value属性、Local Preference属性、路由生成方式、AS_Path属性、Origin属…

学习记录——day18 数据结构 树

树的存储 1、顺序存储 对于普通的二叉树&#xff0c;不适合存储普通的二叉树顶序存储&#xff0c;一般用于存储完全二叉树而言&#xff0c;如果使用顺序存储&#xff0c;会浪费大量的存储空间&#xff0c;因为需要给没有节点的位置留出空间&#xff0c;以便于后期的插入。 所以…

20分钟上手新版Skywalking 9.x APM监控系统

Skywalking https://skywalking.apache.org/ Skywalking是专为微服务、云原生和基于容器的&#xff08;Kubernetes&#xff09;架构设计的分布式系统性能监控工具。 Skywalking关键特性 ● 分布式跟踪 ○ 端到端分布式跟踪。服务拓扑分析、以服务为中心的可观察性和API仪表板。…

兼容浏览器,切换PC端显示PC端,切换H5端显示H5端

兼容浏览器&#xff0c;切换PC端显示PC端&#xff0c;切换H5端显示H5端 Uniapp vue3 Uview 项目 Vue3 Vite Ts ElementPlus PC端 &#xff08;在浏览器PC端&#xff0c;切换H5端兼容显示H5端页面&#xff09; 浏览器H5端 (在浏览器H5端&#xff0c;切换PC端兼容显示PC端…

CSS实现的扫光效果组件

theme: lilsnake 图片和内容如有侵权&#xff0c;及时与我联系~ 详细内容与注释&#xff1a; CSS实现的扫光效果组件 代码 技术栈与框架 Vue3 CSS 扫光效果的原理 扫光效果的原理就是从左到右无限循环的一个位移动画 实现方式 适配文字扫光效果的css .shark-box { …

Stable Diffusion基本原理通俗讲解

Stable Diffusion是一种基于深度学习的图像生成技术&#xff0c;它属于生成对抗网络&#xff08;GANs&#xff09;的一种。简单来说&#xff0c;Stable Diffusion通过训练一个生成器&#xff08;Generator&#xff09;和一个判别器&#xff08;Discriminator&#xff09;&#…

【linux】Shell脚本三剑客之sed命令的详细用法攻略

✨✨ 欢迎大家来到景天科技苑✨✨ 🎈🎈 养成好习惯,先赞后看哦~🎈🎈 🏆 作者简介:景天科技苑 🏆《头衔》:大厂架构师,华为云开发者社区专家博主,阿里云开发者社区专家博主,CSDN全栈领域优质创作者,掘金优秀博主,51CTO博客专家等。 🏆《博客》:Python全…

【OSS对象存储】Springboot集成阿里云OSS + 私有化部署Minio

【OSS对象存储】Springboot集成阿里云OSS 私有化部署Minio 一、摘要二、POM依赖三、配置文件四、表结构设计五、代码实现5.1 代码包结构5.2 API封装5.3 增删改查 六、扩展6.1 Minio配置https访问 一、摘要 掌握阿里云OSS、私有化部署Minio两种对象存储的使用方式运用工厂策略…

Blender 4.2 安装GIS插件步骤

Blender 4 更新以后插件安装变得复杂&#xff0c;插件界面的安装按钮不显示&#xff0c;界面布局改变&#xff0c;怎么安装插件&#xff1a; 1. 在线安装&#xff1a; “编辑”&#xff08;Edit&#xff09;>进入偏好设置&#xff08;Preferences setting&#xff09;>…

机械学习—零基础学习日志(高数10——函数图形)

零基础为了学人工智能&#xff0c;真的开始复习高数 函数图像&#xff0c;开始新的学习&#xff01;本次就多做一做题目&#xff01; 第一题&#xff1a; 这个解法是有点不太懂的了。以后再多研究一下。再出一道题目。 张宇老师&#xff0c;比较多提示了大家&#xff0c;一定…

设计模式12-构建器

设计模式12-构建器 由来和动机原理思想构建器模式的C代码实现构建器模式中的各个组件详解1. 产品类&#xff08;Product&#xff09;2. 构建类&#xff08;Builder&#xff09;3. 具体构建类&#xff08;ConcreteBuilder&#xff09;4. 指挥者类&#xff08;Director&#xff0…

kettle从入门到精通 第七十九课 ETL之kettle kettle读取数据库BLOB字段转换为文件

上一课我们讲解了如何将文件以二进制流的方式写入数据库&#xff0c;本节课我们一起学习下如何将二进制数据读取为文件。 1、将二进制流转换为文件这里主要用到了步骤【文本文件输出】。表输入步骤从表中读取blob字段&#xff0c;java代码定义二进制流转换为文件的全路径&#…