前端合成海报并保存到本地

news/2024/7/20 3:27:13 标签: 前端, javascript, 小程序

近期给AI产品增加了推广返佣的能力,涉及到推广就会有分享裂变,个人的专属分享链接及海报。本次文章主要记录前端合成海报并下载到本地的流程,因为产品运行的平台主要是在小程序和PC浏览器,所以主要也是实现这两个平台的图片下载,接下来开始正文。

浏览器端实现

在实现下载之前首先要将海报内容合并成一张图片。这里用到了 html2canvas 这个库,这个相信很多人都有用到过。

html2canvas可以将网页中的HTML元素转换为Canvas图像,从而实现将网页内容截图的功能。它提供了一种简单的方法来捕捉整个网页或特定的HTML元素,并生成对应的图像数据。

以下是一个简单的示例代码,第一个参数传入需要合并图像的DOM根元素,第二个参数传入相应的参数配置,在回调中即可获取到对应的canvas对象:

javascript">html2canvas(this.$refs.poster.$el, {
    useCORS: true,
    allowTaint: true,
    scale: this.getDPR(),
}).then(canvas => {})

接下来就是将canvas对象转换成图片并下载到本地,通过canvas.toDataURL可以将canvas对象转换为base64的图片地址,再创建一个a标签模拟点击即可触发图片下载到本地。

javascript">const dataURL = canvas.toDataURL('image/jpeg', 0.8);
const link = document.createElement('a');
link.href = dataURL;
link.download = 'poster.png';
// 模拟点击链接,触发下载
link.click();

小程序端实现

小程序实现就较为麻烦一些了,html2canvas小程序里面不支持,可以使用wxml-to-canvas 代替,但是考虑到接入的成本和当前实现的页面比较简单,目前实现是直接用原生canvas绘制海报,大概的代码如下所示,主要就是绘制图片及文本,如果涉及到比较复杂的界面对应的代码复杂度也会升高很多,大家如果有更好的方案欢迎讨论。

javascript">const ctx = wx.createCanvasContext('canvas');
ctx.beginPath();
ctx.drawImage('bg.png', 0, 0, this.canvasWidth, this.canvasHeight);
ctx.setTextAlign('center');
ctx.setFillStyle('#FFFFFF');
ctx.setFontSize(24);
ctx.fillText('海报文本', 150, uni.upx2px(90));
ctx.draw();

图片绘制好了接下来就是下载的过程。

小程序里面下载图片需要用到 wx.canvasToTempFilePath,把当前画布指定区域的内容导出生成指定大小的图片,这里我们传入对应的cavansID即可,在成功的回调中就能获取到图片的临时文件路径 (本地路径)。

javascript">wx.canvasToTempFilePath({
  canvasId: 'poster-canvas',
  success(res) {
      const tempFilePath = res.tempFilePath
  }
})

获取到了本地地址就可以进行图片的保存,但是可能存在用户未设置权限或拒绝了存储到权限,所以下载之前需要进行权限相关的判断及提示引导操作。大概的代码如下:

javascript">// 判断用户授权
wx.getSetting({
    success(res) {
        // 没有权限,发起授权
        if (!res.authSetting['scope.writePhotosAlbum']) {
            wx.authorize({
                scope: 'scope.writePhotosAlbum',
                success() {
                    // 授权成功,可下载
                },
                fail() {
                    // 用户点击拒绝授权,跳转到设置页,引导用户授权
                    wx.openSetting({
                        success() {
                            wx.authorize({
                                scope: 'scope.writePhotosAlbum',
                                success() {
                                    // 可下载
                                },
                                fail() {
                                    this.$showToast("保存失败");
                                }
                            })
                        },
                        fail(res) {
                            this.$showToast("未获得权限保存图片");
                        }
                    })
                }
            })
        } else {
            // 用户已授权,可下载保存到相册
        }
    }
})

权限判断没问题即可调用wx.saveImageToPhotosAlbum传入前面从canvasToTempFilePath获取的tempFilePath进行下载:

javascript">wx.saveImageToPhotosAlbum({
  filePath,
  success() {
      // 保存成功
  },
  fail() {
      // 保存失败
  }
})

最后

在浏览器和小程序中保存图片的过程到此就结束了,可能在不同的设备或DOM元素会存在一定的兼容性,本次主要分享核心的实现逻辑,大家有遇到什么坑欢迎留言讨论~

看完本文如果觉得有用,记得点个赞支持,收藏起来说不定哪天就用上啦~

专注前端开发,分享前端相关技术干货,公众号:南城大前端(ID: nanchengfe)


http://www.niftyadmin.cn/n/4943156.html

相关文章

Qt 8. UDP客户端通信

1. 代码 //UdpClient.h #ifndef UDPCLIENT_H #define UDPCLIENT_H#include <QtNetwork>class Ex2; // 声明类 class UdpClient : public QObject {Q_OBJECT public:explicit UdpClient(Ex2 *ui nullptr);~UdpClient();void Send(QByteArray buf,QHostAddress addr…

讯飞星火认知大模型全新升级,全新版本、多模交互—测评结果超预期

写在前面 版本新功能 1 体验介绍 登录注册 申请体验 2 具体使用 2.1 多模态能力 2.1.1 多模理解 2.1.2 视觉问答 2.1.3 多模生成 2.2 代码能力 2.2.1 代码生成 2.2.2 代码解释 2.2.3 代码纠错 2.2.4 单元测试 2.3 插件功能 2.3.1 PPT生成 2.3.2 简历生成 2.3.4 文档问答 3 其他…

如何写好一篇计算机毕业论文

主题选择&#xff1a;选择一个有足够研究价值和创新性的主题。确保选择的主题与计算机科学领域相关&#xff0c;并对你感兴趣和有一定了解。 文献综述&#xff1a;进行充分的文献调研&#xff0c;了解相关领域的前沿研究和最新进展。在文献综述中&#xff0c;总结和比较已有工…

OpenWrt -- OpenVPN配置ServerClient(TUN模式)

一、前言 目标是两台设备能通过OpenVPN TUN模式建立连接。 准备如下&#xff1a; 设备 友善R2S两台&#xff0c;一台做服务器&#xff0c;一台做客户端。 一台小米R1C&#xff0c;当作网关。 固件 采用openwrt-22.03版本&#xff0c;下载地址:https://downloads.openwrt.org/r…

【初级后台网优—工单处理】舒适圈待久了,你是否还拥有“破圈”的能力?

对于通信网优这个行业是主要分为前台测试和后台优化的&#xff0c;经过小编的普及和大家实际在工作中遇到的应该是很好理解的。这个时候就有同学举手问了&#xff0c;后台优化一般大家说的都是中高级&#xff0c;那么请问有没有初级后台优化&#xff1f;主要是做什么的呢&#…

synchronized锁小计

在Java中&#xff0c;synchronized是一个关键字&#xff0c;用于控制多个线程对共享资源的访问。它是一个修饰符&#xff0c;可以用于方法和块级别synchronized 关键字主要有以下几种用法&#xff1a; 非静态方法的同步&#xff1b;静态方法的同步&#xff1b;代码块。 1 syn…

用于弥散加权MRI的关节各向异性维纳滤光片研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

【TypeScript】接口和对象类型

在 TypeScript 中&#xff0c;接口&#xff08;Interface&#xff09;是一种用于定义对象结构的约定&#xff0c;它描述了对象应该具有的属性和方法。接口提供了一种定义约束&#xff0c;使你能够在编写代码时明确地指定对象的形状和类型。接口在开发中常用于定义对象的结构、类…