Vue 复制、下载 图片和文字

目录

功能描述

图片的格式

复制图片和文字

第一种,直接复制(不推荐)

第二种,画图后复制

下载图片和文字

总结


功能描述

可以简单描述成复制图片和文字,下载图片和文字

前者还好说,比如在图片右键点击,就有浏览器中的复制图片的功能,如下:

所以实现方法应该挺多,而后者如果想要一张图片和文字说明都被下载,那肯定是在一起,下载成一张图片的样子,所以后者的实现方法,我暂时只想到一种,画canvas然后下载。

前者的实现,我有两种,各有优缺点。

说一下,我需要实现的样子,如上面的动图,我是开发了一个弹窗,在弹窗里写了一个图片和一些文字,然后底部有一个复制和下载按钮。

PS:之前考虑使用富文本,因为富文本可以直接粘贴图片和文字到微信输入框和文档,可是一个简单的功能不考虑引入富文本了,比较麻烦。

另外,关于复制和粘贴图片和文字,首先要知道一点,在微信聊天框和文档等富文本环境里直接粘贴图像的支持取决于这些平台的实现。通常情况下,直接从剪贴板中复制图像并粘贴到富文本环境中并不能让图像显示。微信聊天框和文档通常期望用户通过上传图片的方式来插入图片,而不是直接从剪贴板中粘贴。这样可以更好地控制图像的来源和确保安全性。

图片的格式

可以是任何有效的图片 URL,包括基于网络的 URL、base64 编码的数据 URI 或其他支持的格式。只要 img.src 可以成功加载图片即可。我用的是el-image 

以下是一些示例:

  1. 网络图片 URL:

    onst imageUrl = 'https://example.com/path/to/image.jpg'; 
  2. Base64 编码的图片:

    const imageUrl = 'data:image/png;base64,iVBORw...'; // 替换为实际的 base64 编码 
  3. 其他格式的图片 URL:

    const imageUrl = 'data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100"><rect width="100%" height="100%" fill="red" /></svg>'; 

无论使用哪种格式,只要能够被 Image 对象成功加载,就可以用于在 canvas 中绘制。在实际使用中,确保 Url 是有效的,不会导致跨域问题(如果是网络图片),并且可以被浏览器加载。


复制图片和文字

图片和文字,一般是图片和文字说明,如果只是复制,那么一般需要能够在文档,微信聊天的输入框等地方能够粘贴,实现这种就可以了,那也就是要么将这个带图片和文字的DOM复制下来,要么也就是跟下载一样,画一个canvas ,然后复制。二选一,详细描述在下面。

所以有几个能复制的API就不太使用,比如:浏览器的 Clipboard ,提供了它 ClipboardItem,但并不是所有浏览器都支持将图像粘贴到富文本编辑器中。

第一种,直接复制(不推荐)

第一种方式是先把图片和文字的DOM给一个ref,然后就复制这个dom,调用这document.execCommand,就能实现,代码如下:

        <div class="image-container" style="flex-direction: column;" ref="imageDom"><el-imagestyle="width: 200px; height: 200px":src="url"fit="fill"></el-image>  <span class="text">{{ida}}</span></div>
this.$nextTick(() =>{//nextTick,当前dom渲染完毕的回调//打印获取的domconsole.log('imageDom', this.$refs.imageDom) const selection = window.getSelection()const range = document.createRange()//传入domrange.selectNode(this.$refs.imageDom) selection.addRange(range)document.execCommand('copy') //document.execCommand 已经被废弃// 清除缓存selection.removeAllRanges()this.$Message.success("复制成功!");})

实现效果如下,点击复制后到一个文档,点击粘贴,内容如下:

白色的背景估计是dom的背景色,也粘贴下来了,并且我在Dom里设置图片大小是200px高宽,这个粘贴的是原始大小,我是缩小了后才能看到这样子的。

但是!这种方法虽然可以在文档里粘贴,但是微信输入框不可以!只能粘贴文字:

所以我不推荐的原因有两个,

1.不能在聊天输入框里粘贴的话,那么这个复制功能应用场景就比较局限

2.不能保留DOM的样式,比如无法粘贴文本的字体大小颜色之类的,有些富文本的可以。 

第二种,画图后复制

用Canvas画出图像和文本,然后通过 Clipboard API 复制到剪贴板。这种方式可以确保在粘贴时能够包含图像和文本。这个需要注意一下浏览器兼容性, Canvas、Blob 和 Clipboard API 的使用在大多数现代浏览器中是支持的,但在一些较老的浏览器中可能存在问题。建议在目标浏览器上进行测试,确保功能正常。

不过在移动端设备上,可能需要特别小心兼容性问题。如果在某些浏览器或环境中发现问题,可以考虑降级到一种更普遍支持的方案,如直接下载图片和文本的合并文件,然后手动上传,正好下下面也考虑开发下载功能。

    this.$nextTick(() => {// 获取图片和文本const imageUrl = 'https://file.iviewui.com/images/image-demo-13.jpg'; // 替换为实际的图片URLconst text = '123456';// 创建一个 canvas 元素const canvas = document.createElement('canvas');const ctx = canvas.getContext('2d');// 创建一个 Image 元素,用于加载图片const img = new Image();img.crossOrigin = 'Anonymous'; // 处理跨域图片img.src = imageUrl;img.onload = () => {// 设置 canvas 的尺寸const canvasWidth = img.width;const canvasHeight = img.height + 50; // 考虑到文字的高度,增加 50px 的高度canvas.width = canvasWidth;canvas.height = canvasHeight;// 绘制白色背景ctx.fillStyle = '#ffffff';ctx.fillRect(0, 0, canvasWidth, canvasHeight);// 绘制图片ctx.drawImage(img, 0, 0, canvasWidth, img.height);// 绘制文本ctx.font = 'bold 14px Arial';ctx.fillStyle = '#000';ctx.textAlign = 'center'; // 文本水平居中ctx.textBaseline = 'top';// 设置文本距离图片底部的边距const textMargin = 10;const textX = canvasWidth / 2; // 文本横向居中const textY = img.height + textMargin;ctx.fillText(text, textX, textY);// 复制 canvas 内容到剪贴板canvas.toBlob((blob) => {const clipboardItem = new ClipboardItem({ 'image/png': blob });navigator.clipboard.write([clipboardItem]).then(() => {console.log('Canvas content copied to clipboard');});});};});

这里画图时,我是给图片设置了一个宽度200px,画布高250px,所以复制下的图片就100+KB,原图可能几MB,也可以不压缩,直接在原图的高宽上加一个文字的高度就行,但是这种画出来的图不协调。

上面是复制的时候去画图,当然也可以选择打开弹窗时就显示一张画好的图,然后点击复制直接复制。其实就是上面的代码拆开,然后加了一个canvas的dom,可以不看。

<canvas ref="canvas"></canvas>
// 打开弹窗时this.$nextTick(() => {const canvas = this.$refs.canvas;this.drawCanvas(canvas);});
// 画图
drawCanvas(canvas) {const ctx = canvas.getContext('2d');const img = new Image();img.crossOrigin = 'Anonymous';img.src = this.url;img.onload = () => {const canvasWidth = 400;const canvasHeight = 400 + 50;canvas.width = canvasWidth;canvas.height = canvasHeight;ctx.fillStyle = '#ffffff';ctx.fillRect(0, 0, canvasWidth, canvasHeight);ctx.drawImage(img, 0, 0, canvasWidth, 400);ctx.font = 'bold 14px Arial';ctx.fillStyle = '#000';ctx.textAlign = 'center';ctx.textBaseline = 'top';const textMargin = 10;const textX = canvasWidth / 2;const textY = 400 + textMargin;ctx.fillText(this.ida, textX, textY);};},// 复制
// 在点击复制时将 Canvas 的内容复制到剪贴板const canvas = this.$refs.canvas;canvas.toBlob((blob) => {const clipboardItem = new ClipboardItem({ 'image/png': blob });navigator.clipboard.write([clipboardItem]).then(() => {console.log('Canvas content copied to clipboard');});});

 实现效果如下:

 我是先粘贴到微信聊天框,然后粘贴到文档里,粘贴后的图片大小压缩了一部分,如果只是看图片的话,这种还可以看,压缩的不太过分。

下载图片和文字

下载是将canvas 复制然后通过<a>标签创建链接在新标签页下载的手段,比较常见。

// 复制 canvas 内容const canvas = this.$refs.canvas;canvas.toBlob((blob) => {const clipboardItem = new ClipboardItem({ 'image/png': blob });navigator.clipboard.write([clipboardItem]).then(() => {this.$Message.info('下载中...')});});// 创建下载链接const link = document.createElement('a');link.href = canvas.toDataURL('image/png');link.download = 'canvas_image.png';// 将链接添加到页面document.body.appendChild(link);// 触发链接点击事件const clickEvent = new MouseEvent('click', {bubbles: true,cancelable: false,view: window});link.dispatchEvent(clickEvent);// 移除链接document.body.removeChild(link);


总结

暂时只想到这两种办法,然后基本都是通过HTML5的Clipboard 来实现复制。

核心代码: 

 canvas.toBlob((blob) => {const clipboardItem = new ClipboardItem({ 'image/png': blob });navigator.clipboard.write([clipboardItem]).then(() => {this.$Message.info('下载中...')});});
  1. Canvas API: canvas.toBlob 方法用于将 Canvas 上的内容转换成一个 Blob 对象。在你的代码中,blob 就是包含 Canvas 内容的 Blob 对象。Blob 是二进制大对象(Binary Large Object)的缩写,它是一个表示任意类型数据的不可变、原始数据的类文件对象。在这里,blob 包含了 Canvas 上绘制的图像和文本。

    canvas.toBlob((blob) => { // 在这里,blob 包含了 Canvas 上绘制的图像和文本 }); 
  2. Clipboard API: ClipboardItem 是 Clipboard API 中的一个对象,它表示要复制到剪贴板的数据项。在这里,创建了一个包含图像的 ClipboardItem 对象,并指定了 MIME 类型为 'image/png'。然后,通过 navigator.clipboard.write 方法将 ClipboardItem 对象写入剪贴板。

    const clipboardItem = new ClipboardItem({ 'image/png': blob }); navigator.clipboard.write([clipboardItem]).then(() => { // 复制到剪贴板成功后的回调 }); 

    在这个过程中,浏览器会向用户请求权限来访问剪贴板,因此需要在用户同意后执行复制操作。

总体而言,这段代码的目的是在 Canvas 中绘制图像和文本,将绘制的内容转换成 Blob 对象,然后通过 Clipboard API 将 Blob 对象复制到剪贴板中。在这个过程中,用户可能会看到有关剪贴板操作的浏览器提示。OVER。

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

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

相关文章

文心一言 VS 讯飞星火 VS chatgpt (162)-- 算法导论13.1 2题

二、用go语言&#xff0c;对图13-1中的红黑树&#xff0c;画出对其调用TREE-INSERT 操作插人关键字 36 后的结果。如果插人的结点被标为红色&#xff0c;所得的树是否还是一棵红黑树?如果该结点被标为黑色呢? 文心一言&#xff0c;代码不能运行&#xff1a; 在Go语言中&…

通过生成表征的自条件图像生成

文章目录 摘要1、简介2、相关工作3、方法4、结果4.1、设置4.2、无条件类别的生成4.3、无分类器指导4.4、消融实验4.5、计算成本4.6、定性结果 5、讨论 摘要 https://arxiv.org/pdf/2312.03701.pdf 本文提出了表示条件图像生成&#xff08;Representation-Conditioned Image Ge…

python绘制烟花特定爆炸效果,python画烟花绽放出字

大家好&#xff0c;小编来为大家解答以下问题&#xff0c;python绘制烟花特定爆炸效果&#xff0c;python画烟花绽放出字&#xff0c;今天让我们一起来看看吧&#xff01; 本文参考了https://blog.csdn.net/weixin_43943977/article/details/102691392博主的樱花以及https://bl…

Python办公自动化Day1

目录 文章声明⭐⭐⭐让我们开始今天的学习吧&#xff01;xlwt创建Excelxlrd读取Excelxlutils修改Excelxlwt设置样式常见的字体样式单元格宽高内容对齐方式设置单元格边框设置背景颜色样式整合起来的写法 文章声明⭐⭐⭐ 该文章为我&#xff08;有编程语言基础&#xff0c;非编…

Ubuntu及Docker 安装rabbitmq

安装ubuntu 前 先暴露端口&#xff1a; 5672 用于与mq服务器通信用 15672 管理界面使用的端口 docker命令&#xff1a;docker run -itd --name ubuntu -p 5672:5672 -p 15672:15672 ubuntu 进入docker : docker exec -it ubuntu /bin/bash 步骤&#xff1a; 1. 更新安装源…

otter-harbor同步

一. 部署及依赖 otter Github (一). 服务启动 1. mysql 5.6版本以上&#xff0c;作为 otter-manger 使用的数据库 # mysql docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD123456 -d mysql:5.7 --character-set-serverutf8mb4 --collation-serverutf8mb4_un…

Alpha突触核蛋白神经退行性疾病

Alpha突触核蛋白科研背景 ● Alpha突触核蛋白约 15kDa, 140个氨基酸 ● StressMarq在E. coli中过表达人源基因然后将蛋白从细胞质基质中纯化出来 ● 未折叠的alpha突触核蛋白单体在12% SDS-PAGE上为~15 kDa的条带 StressMarq/欣博盛生物的Alpha突触核蛋白有以下两类&#xf…

Open3D 最小二乘拟合平面(直接求解法)

目录 一、算法原理二、代码实现三、结果展示本文由CSDN点云侠原创,原文链接。爬虫自重。 一、算法原理 平面方程的一般表达式为: A x + B y + C z

docusaurus简介及使用心得

docusaurus简介 Docusaurus 是 Facebook 专门为开源项目开发者提供的一款易于维护的静态网站创建工具&#xff0c;使用 Markdown 即可更新网站。构建一个带有主页、文档、API、帮助以及博客页面的静态网站&#xff0c;只需5分钟。 同类竞品还有vuepress&#xff0c;docusaurus…

华夏ERP getAllList;.ico敏感信息泄露漏洞

漏洞描述 华夏ERP是基于SpringBoot框架和SaaS模式&#xff0c;立志为中小企业提供开源好用的ERP软件&#xff0c;目前专注进销存财务功能。主要模块有零售管理、采购管理、销售管理、仓库管理、财务管理、报表查询、系统管理等。支持预付款、收入支出、仓库调拨、组装拆卸、订…

个性化TikTok外贸工具定制!突破营销新境界!

随着全球化的加速发展&#xff0c;外贸行业正面临着前所未有的机遇和挑战&#xff0c;在这个竞争激烈的市场环境中&#xff0c;如何脱颖而出&#xff0c;吸引更多的潜在客户&#xff0c;成为每个外贸企业亟待解决的问题&#xff0c;而个性化TikTok外贸工具的定制&#xff0c;正…

尺寸公差分析与尺寸链计算软件-DTAS3D到底能给我们带来哪些价值?

【技能】DTAS3D能给我们带来哪些价值&#xff1f; DTAS3D是一款高度集成的公差分析软件&#xff0c;旨在为产品开发团队提供准确的建议&#xff0c;从而放心地将设计发布给制造部门。下面是DTAS3D的关键价值和应用: 1.与三维CAD无缝集成: DTAS3D与三维CAD软件 (CATIA、NX、Cr…

MySQL中CASE when 实战

CASE 语法 CASEWHEN condition1 THEN result1WHEN condition2 THEN result2WHEN conditionN THEN resultNELSE result END; 将表中的内容转换为右边的形式&#xff1a; 1、创建表&#xff0c;创建数据 CREATE TABLEchapter10_7 (order_id VARCHAR(255) NULL,price VARCHAR(25…

大模型三级跳:2023年AI行业的崭新篇章

2023年&#xff0c;大模型的发展如同一场三级跳&#xff0c;迅速跃升至新的高度。从ChatGPT的火爆&#xff0c;到众多大厂纷纷入场&#xff0c;再到百模大战的激烈角逐&#xff0c;这一年的AI行业充满了竞争与变革。 首先&#xff0c;大模型的崛起标志着AI技术进入了一个新的阶…

uniapp中如何使用百度tts生成文字语音并播放

第一步先在百度云里面申请一个tts应用&#xff0c;这里默认你们都会了哈&#xff0c;申请完是这样的 第二步在manifest.json注册一下 第三步进项目,先获取token handleGetToken() {// client_id和client_secret就是百度API Key和Secret Keyuni.request({url: https://aip.ba…

TKEStack容器管理平台实战之部署wordpress应用

TKEStack容器管理平台实战之部署wordpress应用 一、TKEStack介绍1.1 TKEStack简介1.2 TKEStack特点1.3 TKEStack架构图 二、kubernetes集群介绍2.1 k8s简介2.2 k8s架构图 三、本次实践介绍3.1 实践环境要求3.2 本次实践环境规划3.3 本次实践简介 四、安装容器管理平台4.1 安装T…

ACL实现固定时间访问资源——项目

文章目录 一、前言二、项目拓扑三、项目需求四、配置思路五、配置步骤1 IP地址2 端口类型3 静态路由4 流策略 六、结语 免责声明 本文旨在提供信息和解决问题的建议&#xff0c;观点和建议可能不适用于个人情况&#xff0c;仅供参考&#xff01;&#xff01;&#xff01; 文章中…

残差网络学习

参考B站同济子豪兄的Resnet讲解 网络退化&#xff0c;不是梯度消失&#xff08;根本没有开始学习&#xff09;&#xff0c;梯度爆炸&#xff0c;过拟合。 不需要再拟合复杂底层的那个映射了&#xff0c;原来输入的基础上你需要进行哪些偏移哪些修改 残差预测值和真实值的偏差 一…

锐捷配置PVLAN

一、实验拓扑 二、实验目的 PVLAN可以通过主VLAN和辅助VLAN的概念&#xff0c;部署隔离技术&#xff0c;实现用户间的互访控制。 三、实验配置 SW2 Ruijie >enable Ruijie #configure terminal Ruijie (config)#vlan 20 Ruijie (config-vlan)#private-vlan community …

视频号小店如何运营?流程跑通就成功了一大半!

我是电商珠珠 视频号小店是视频号团队发展的电商平台&#xff0c;目前处于项目的风口期&#xff0c;很多有想法的新手并不知道应该怎么去运营&#xff0c;今天我就来给大家讲一下。 一、入驻 视频号小店入驻的门槛较高&#xff0c;需要准备一张企业的营业执照&#xff0c;身…