uniapp生成自定义(分享)图片并保存到相册

需求描述

在这里插入图片描述
在一个页面中底部有个保存图片的功能,点击能够保存一张生成的自定义表格图片。
第一眼见到这个需求 自己会出现了两个问题

  1. 如何去处理图片中的自定义内容以及样式
  2. 如何将自定义内容转化成图片
    至于保存图片,uniapp有对应的api去实现uni.saveImageToPhotosAlbum,不做赘述

实现效果展示

请添加图片描述
下面就是生成的图片在这里插入图片描述

实现步骤

大致划分成以下几个步骤
1、需要在目标页面画出图片内容的html代码,并置于于屏幕可视区域外形成隐藏的效果(不是display:none隐藏元素)
2、需要将html转成canvas的形式,再通过toDataURL方法转成base64图片形式
3、将base64转换成临时图片路径,即可展示出,并下载

已知需要用到两个插件来帮助实现
一个是html转canvas的插件 html2canvas可通过npm下载

npm install html2canvas -D

一个是将base64图片格式转本地地址的Dcloud插件image-tools

1、画需要生成图片的元素

即就是生成图片的样式 还是需要我们自己来搞出来。可以封装成一个组件形式,这里就不贴代码,因为这不是核心逻辑,况且大家需要生成图片的样式都不一样,唯一需要注意的是,这块元素是要脱离文档流,并置于屏幕外,不让用户看到

将生成图片的代码封装成一个组件,如下 需要声明一个id 为后续转canvas做准备

<KitcalculatorTable id="pagePoster"/>

并将这块区域通过固定定位置于可视区外,这样就看不到了,不能用v-if或者v-show、display:none去隐藏,这样在后续html转canvas是失败的,无法获取到该区域元素

position: fixed;
top: -999999rpx;
background-color: #fff;
padding: 30rpx;

2将html转成canvas的形式,再转成base64图片形式

<template><view class="html2Canvas" id="pagePoster"><view class="table"><view class="kitCalculatorName">{{ pageData.kitCalculatorName }}</view><KitcalculatorTable :tableData="tableData" :isSumData="true" /><view class="average-data"><view style="margin-right: 50rpx">件套平均价格:{{ pageData.averagePriceOneDesc }}</view><view v-if="visiblePrice2">平均价格2:{{ pageData.averagePriceTwoDesc }}</view></view></view><view class="bottom-logo"><img class="code" :src="codeImage" /><view><view class="">报盘计算器,长按识别二维码使用</view><img class="logo" :src="logoImage" /></view></view></view><view class="muji-button" style="margin: 0 24rpx" @click="canvasImage.generateImageSave">保存图片</view><view class="muji-button" @click="canvasImage.generateImageShare">分享</view>
</template>
<script lang="renderjs" module="canvasImage">
import html2canvas from 'html2canvas'
export default {mounted() {},methods: {generateImageSave(){this.generateImage('save')},generateImageShare(){this.generateImage('share')},// 生成图片需要调用的方法generateImage(methodType) {this.$ownerInstance.callMethod('openLoading', '正在生成图片~')setTimeout(() => {const dom = document.getElementById('pagePoster') // 需要生成图片内容的 dom 节点html2canvas(dom, {width: dom.clientWidth, //dom 原始宽度height: dom.clientHeight,scrollY: 0, // html2canvas默认绘制视图内的页面,需要把scrollY,scrollX设置为0scrollX: 0,useCORS: true, //支持跨域// scale: 2, // 设置生成图片的像素比例,默认是1,如果生成的图片模糊的话可以开启该配置项}).then((canvas) => {// 生成成功// html2canvas 生成成功的图片链接需要转成 base64位的urlthis.$ownerInstance.callMethod('receiveRenderData',canvas.toDataURL('image/png'))}).catch(err=>{this.$ownerInstance.callMethod('_errAlert',`【生成图片失败,请重试】${err}`)})}, 300)},}
}
</script>
<script>
import { pathToBase64,base64ToPath} from 'image-tools';
export default {props: {pageData: {type: Object,default: () => {return {};},},},data() {return {temUrl: '', //生成的临时路径图片codeImage: '', // 件套二维码图片logoImage: '', // logo图片};},created() {// 处理静态图片 转为base64this.actionImage();},methods: {// 处理已知静态图片 转base64格式actionImage() {this.turnBase64Image(require('@/static/logo/down-code.png'), 'codeImage');this.turnBase64Image(require('@/static/logo/muji-logo.png'), 'logoImage');},// 将图片转为base 64 位urlturnBase64Image(img, key) {uni.getImageInfo({src: img,success: (image) => {pathToBase64(image.path).then((base64) => {this[key] = base64;}).catch((error) => {console.log('转换失败:', error);});},fail: (err) => {console.log('将本地图片转为base 64报错:', err);},});},/* 将base64 位的图片路径转换为 临时路径 */loadBase64Url(imageStr) {const that = this;base64ToPath(imageStr).then((path) => {this.temUrl = path;this.closeLoading()this.saveImg()}).catch((error) => {console.error('临时路径转换出错了:', error);});},// 获取生成的base64 图片路径receiveRenderData(val) {const url = val.replace(/[\r\n]/g, ''); // 去除base64位中的空格this.loadBase64Url(url);},// 报错alert_errAlert(content) {uni.showModal({title: '提示',content: content,});},saveImg() {uni.saveImageToPhotosAlbum({filePath: this.temUrl,success: function () {uni.showToast('保存图片成功');}});},},
};
</script>

需要注意的两点是,这里要新建一个script节点,将语言改成renderjs的形式 在这之内做html转canvas的操作
再就是需要把生成图片中的已知静态图片 如下载二维码、企业logo转换成base64的形式

保存图片

最后就是点击保存后,调用canvasImage下的generateImage去生成图片,拿到base64格式图片通过image-tools的base64ToPath方法去转成临时路径再下载就ok了

题外话

这里涉及到renderjs的通讯知识,还是有点坑的
比如在renderjs模块调用script的方法是可以直接

this.$ownerInstance.callMethod('script内方法名',需要带的参数)

目前只了解可以在dom去调用renderjs方法,在script内貌似不能直接用。大家就要根据需求去灵活使用这个东西

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

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

相关文章

【部署篇】Docker配置MySQL容器+远程连接

一、前言 上篇文章在部署nestjs时&#xff0c;由于docker访问不了主机的localhost&#xff0c;所以无法连接主机数据库。所以我们只能在docker中额外配置一个数据库&#xff0c;映射到主机上&#xff0c;然后可以通过ip地址访问。 在本篇文章我们会在docker中创建一个mysql&a…

Vue3源码reactive和readonly对象嵌套转换,及实现shallowReadonly

前言 官方文档中对reactive的描述&#xff1a; 响应式转换是“深层”的&#xff1a;它会影响到所有嵌套的属性。一个响应式对象也将深层地解包任何 ref 属性&#xff0c;同时保持响应性。 官方文档中对readonly的描述: 只读代理是深层的&#xff1a;对任何嵌套属性的访问都将是…

web:[BUUCTF 2018]Online Tool

题目 打开页面显示如下&#xff0c;进行代码审计 上述代码主要功能是接收‘host’参数&#xff0c;后使用nmap扫描主机端口 首先检查是否存在HTTP_X_FORWARDED_FOR头&#xff0c;若存在&#xff0c;将值赋值给EMOTE_ADDR,是为了跟踪用户真实的IP地址 后用检查get‘host’是否…

验证k8s中HPA功能及测试

部署 使用yaml部署服务 apiVersion: apps/v1 kind: Deployment metadata:name: php-apachenamespace: tools spec:replicas: 1selector:matchLabels:app: php-apachetemplate:metadata:labels:app: php-apachespec:containers:- name: php-apacheimage: registry.cn-beijing.…

Ubuntu18.04平台下Qt开发程序打包的一些问题总结

目录 前言 一、在Ubuntu18.04开发环境下打包有两种方式 1、利用linuxdeployqt软件进行打包 2、利用编写shell脚本的方式进行打包 二、详细介绍shell脚本打包的方式 1、新建一个空的文件夹 2、准备脚本copylib.sh 3、准备脚本xxxx.sh。 4、给上述两个脚本添加可执行权限…

Java虚拟机运行时数据区结构详解

Java虚拟机运行时数据区结构如图所示 程序计数器 程序计数器&#xff08;Program Counter Register&#xff09;是一块较小的内存空间&#xff0c;它可以看作是当前线程所执行的字节码的行号指示器。 多线程切换时&#xff0c;为了能恢复到正确的执行位置&#xff0c;每条线程…

计算机毕业设计选题推荐-二手交易跳蚤市场微信小程序/安卓APP-项目实战

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…

通信原理板块——脉冲编码调制(PCM)

微信公众号上线&#xff0c;搜索公众号小灰灰的FPGA,关注可获取相关源码&#xff0c;定期更新有关FPGA的项目以及开源项目源码&#xff0c;包括但不限于各类检测芯片驱动、低速接口驱动、高速接口驱动、数据信号处理、图像处理以及AXI总线等 1、脉冲编码调制PCM原理 将模拟信号…

6.2 List和Set接口

1. List接口 List接口继承自Collection接口&#xff0c;List接口实例中允许存储重复的元素&#xff0c;所有的元素以线性方式进行存储。在程序中可以通过索引访问List接口实例中存储的元素。另外&#xff0c;List接口实例中存储的元素是有序的&#xff0c;即元素的存入顺序和取…

搭建成功simulink-stm32硬件在环开发环境

本次实验所使用的软件版本和硬件平台参数如下&#xff1a; Matlab版本: 2021b STM32硬件平台&#xff1a;YF_STM32_Alpha 1R4(参考自STM32 Nucleo F103RB官方开发板) YF_STM32_Alpha开发板 STM32 Nucleo F103RB 开发板 2.1 STM32硬件支持包下载 读者朋友平时使用的是和谐版M…

洗眼镜超声波清洗机用什么水清洗、小型超声波清洗机推荐

洗眼镜的超声波清洗机可以用清水清洗&#xff0c;因为超声波频率可以把眼镜缝隙中的脏污渍给振动出来&#xff0c;所以清水槽内放清水就可以了。像清洗一些机器零件的话&#xff0c;污渍比较重可以适当的家电清洁液进去清洗&#xff0c;这样清洗完的效果会比较好。戴眼镜的朋友…

Adobe家里的“3D“建模工 | Dimension

今天&#xff0c;我们来谈谈一款在Adobe系列中比肩C4D的高级3D软件的存在—— Dimension。 Adobe Dimension &#xff0c;其定位是一款与Photoshop以及Illustrator相搭配的3D绘图软件。 Adobe Dimensions与一般的3D绘图软件相较之下&#xff0c;在操作界面在功能上有点不大相同…

SDL2 播放音频数据(PCM)

1.简介 这里以常用的视频原始数据PCM数据为例&#xff0c;展示音频的播放。 SDL播放音频的流程如下&#xff1a; 初始化音频子系统&#xff1a;SDL_Init()。设置音频参数&#xff1a;SDL_AudioSpec。设置回调函数&#xff1a;SDL_AudioCallback。打开音频设备&#xff1a;SD…

NewStarCTF2023 Reverse Week3---Let‘s Go Wp

分析 程序打开后结合题目可以发现是 GO语言。 在GO语言中&#xff0c;main_init 要先于 main 函数运行。 在这里对一个iv做了处理。 用插件Signsrch发现AES加密 知道是AES后&#xff0c;就需要找密文&#xff0c;key和iv了。 密文应该就是前面的十六进制字符串。 key和i…

二百零三、Flume——Flume实时采集数据频率为1s的高频率Kafka数据直接写入ODS层表的HDFS文件路径下

一、目的 在离线数仓中&#xff0c;需要用Flume去采集Kafka中的数据&#xff0c;然后写入HDFS中。 由于每种数据类型的频率、数据大小、数据规模不同&#xff0c;因此每种数据的采集需要不同的Flume配置文件。玩了几天Flume&#xff0c;感觉Flume的使用难点就是配置文件 二、…

医疗项目的需求分析以及开发流程

一.项目的背景以及需求 1.项目背景 1.政策层面来看&#xff0c;近年来我国政府相关部门陆续颁发了支持数字医疗行业发展的相关政策&#xff0c;“互联网医疗”政策逐渐明确完善&#xff0c;为数字医疗行业发展提供支持&#xff0c;行业迎来政策福利期。 其次&#xff0c;从经济…

熟悉 Unity HDRP设置以提高性能

HDRP Version 10 了解如何利用高清晰度渲染管道(HDRP)设置&#xff0c;以最大限度地提高性能&#xff0c;并一次实现强大的图形。 随着Unity 2020 LTS及以后的HDRP版本10的发布&#xff0c;HDRP包继续优先考虑其用户友好的界面&#xff0c;灵活的功能&#xff0c;稳定性和总体…

第3章:搜索与图论【AcWing】

文章目录 图的概念图的概念图的分类有向图和无向图 连通性连通块重边和自环稠密图和稀疏图参考资料 图的存储方式邻接表代码 邻接矩阵 DFS全排列问题题目描述思路回溯标记剪枝代码时间复杂度 [N 皇后问题](https://www.luogu.com.cn/problem/P1219)题目描述全排列思路 O ( n ! …

什么是美国服务器,有哪些优势,适用于什么场景?

​  在互联网发展的过程中&#xff0c;服务器扮演着至关重要的角色。而美国作为全球信息技术的中心&#xff0c;其服务器在全球范围内受到广泛关注。  美国服务器是指在美国本土机房搭建并运行的服务器。其拥有带宽大、优质硬件、售后运维好、位置优越、数据安全性高以及免备…

《视觉SLAM十四讲》-- 后端 2

文章目录 09 后端 29.1 滑动窗口滤波和优化9.1.1 实际环境下的 BA 结构9.1.2 滑动窗口法 9.2 位姿图9.2.1 位姿图的意义9.2.2 位姿图优化 09 后端 2 9.1 滑动窗口滤波和优化 9.1.1 实际环境下的 BA 结构 由于计算机算力的限制&#xff0c;我们必须控制 BA 的规模&#xff0c…