component-后端返回图片(数据)前端进行复制到剪切板

news/2024/12/21 11:46:27/
1.前言
  1. Base64编码‌:将图片转换为Base64编码的字符串,然后通过HTTP协议传输到前端前端接收到Base64字符串后,可以通过JavaScript将其解码并显示为图片。这种方式适合小图片,如logo或验证码,因为Base64编码后的字符串较长,可能会影响页面加载速度和性能‌12。

  2. URL地址‌:将图片上传到服务器,获取图片的URL地址后,将该URL地址传输到前端前端通过设置<img>标签的src属性为该URL地址来显示图片。这种方式适用于大图片,因为不需要将图片数据直接传输到前端,而是通过URL地址访问服务器上的图片资源‌。

  3. 字节流‌:通过HTTP响应的输出流直接将图片以二进制形式传输到前端前端接收到图片的字节流后,可以直接在<img>标签的src属性中设置data:image/png;base64,前缀,并附加图片的Base64编码字符串来显示图片。这种方式适用于需要实时处理或展示图片的场景‌

2. URL地址形式
javascript"><template><div class="copyAll"><a-form class="search"><!-- 复制二维码 --><a-form-item label="二维码"><div class="codeAll"><div class="codeCopy"><img src="https://img0.baidu.com/it/u=3383325011,2141463052&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1424" alt=""></div> <a-button type="primary" @click="copyImageToClipboard('https://img0.baidu.com/it/u=3383325011,2141463052&fm=253&fmt=auto&app=138&f=JPEG?w=800&h=1424')">复制二维码</a-button></div></a-form-item></a-form></div>
</template><script>
export default {name: 'Copy',data () {return {}},methods: {// 通过 Canvas,图像绘制到画布上,然后将其转换为支持的格式(如 PNG),复制到剪贴板。async copyImageToClipboard(imageUrl) {  // 异步请求const response = await fetch(imageUrl);  const contentType = response.headers.get('Content-Type') || 'image/png';  const isSupportedImageType = contentType.startsWith('image/');  if (!isSupportedImageType) {  throw new Error('Unsupported image type');  }  const blob = await response.blob(); // 获取图像的 Blob 对象const imgElement = new Image(); // 创建 Image 对象imgElement.src = URL.createObjectURL(blob); // 将 Blob 转为 URLreturn new Promise((resolve, reject) => {imgElement.onload = async () => {const canvas = document.createElement('canvas'); // 创建 Canvasconst ctx = canvas.getContext('2d'); // 获取 Canvas 上下文if (contentType === 'image/gif') {// 处理 GIF,直接使用 GIF Blobconst item = new ClipboardItem({ 'image/gif': blob });  // 使用 GIF 格式await navigator.clipboard.write([item]); // 写入剪贴板resolve();} else {// 处理 JPG/JPEG/PNG,转换为 PNGcanvas.width = imgElement.width; // 设置宽度canvas.height = imgElement.height; // 设置高度ctx.drawImage(imgElement, 0, 0); // 将图像绘制到 Canvas// 转换为 Blob,使用 'image/png' 作为 MIME 类型canvas.toBlob(async (newBlob) => {const item = new ClipboardItem({ 'image/png': newBlob });  // 使用 PNG 格式await navigator.clipboard.write([item]); // 写入剪贴板resolve(); // Promise 成功}, 'image/png');}};imgElement.onerror = reject; // 处理错误});}}
}
</script>
<style lang="less" scoped>
// 全部
.copyAll{padding: 30px;
}
// 二维码
.codeAll{display: flex;flex-direction: row;width: 220px;align-items: center;
}
// 二维码展示
.codeCopy{height: 150px;width: 110px;// background-color: red;img{height: 100%;width: 100%;}
}
// 按钮间距
/deep/.ant-btn-primary{margin-left: 10px !important;
}
</style>
3.后端返回Base64编码的字符串 进行复制图片
3.1 具体代码
javascript"><template><div><img :src="imgSrc" alt="" class="qrcode"><button @click="copyImage">复制图片</button></div>
</template><script>
export default {data() {return {base64Image: 'iVBORw0KGgoAAAANSUhEUgAAAZAAAAGQCAIAAAAP3aGbAAAL00lEQVR42u3cQY6kMBBE0br/pekztESSEfb7a8RQJv08C9S/R5JK+lkCScCSJGBJApYkAUuSgCUJWJIELEkCliRgSRKwJAlYkoAlScCSJGBJApYkAUuSgCUJWJJUBtavpLee/7/3WXupYc+z9ZzT83Dq82/tR2ABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWPMf5rVsjBYop9etZT0dhDkfVAMLWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABay8BUp7/rS2oGlZ57QDEljAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMBKXaDkgd7aALdBkwY0sIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhaw7garBQgb4xtQfuU9Yd2wH4EFLGABC1heGLCAZf6BBSxgAQtYFghYwAIWsLwwYAHL/AMLWMACFrAsELCABaybwGoZLNe7/obrT4IeWK53PbCABSzXux5YwAKW610PLGC53vXAAhawXO96YAELWK53PbCA5XrXA+tEsNp7a0EnXsyXg3vb75o+mB/N7VlgAQtYwAIWsIAFLAELWMACFrCABSxgAQtYwAIWsAQsYAELWMACFrCABawDwUrbSNOD1fIha9o6pwHaAnHLAVz/pTuwgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMAC1jJYW4OeNlhbIKbd/7aNlAZxGqzAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMDKHsQWKFvgTh7QL9t6X+33+XJugQUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCANX8fg/vu79qCLw3WtPfYPs/AAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMDKeJEtG3v6d9kA39xnq1NBBxawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACVsagn7rxnrBOhSYNgjRwp9cBWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtY3w7Q1vVbAKWtWzvcWwdDCxzAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMDqBOvUgWsHd+v+7QfP9L/bAvqXzw8sYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABay9jdTyPC33f8JqWYf297K1v4AFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawTgdreiG2XnwLNG+tz0kDPbEOLXPSvs7AAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMCaefFbgzU9cC0bb+v3bm2MLeitA7CABSxgAQtYwAIWsIAFLGDZqNYBWMACFrCABSxgAQtYwAIWsGxU6wAsYAELWHeD1fKBZfuGb4cv7SDZ+r1vPefWgZEAHLCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsPY2dtpGSoMybf0TNkbCvmifW2ABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYGW/mOnBSrvPNDRbQKSBu/WcaeufDB+wgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMAC1olgtQ9KywaeHqD297V1YNwGesL6AAtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGDdBFb7QGwBcSoEW1C2gN4OIrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwALWpWC1bNStQU87GNI26tZ73zoYbpgrYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABawTwWoZ6LcW+tSBS3vOtIMz7YBsgRhYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1idgzL9PL+StiBIg6nld23tr0bIgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrBuAmt6g23dp+UFp63/FtBb92mf82TogQUsYAELWMACFrCABSxgAQtYwAKWjQcsYAELWMACFrCABSxgAQtYwLLxgAUsYAELWMA6ESwfNH6zAbY+mJx+zrQDpv1ASviwM/rDUWABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAWsULBu+7BwerBaNtLW82/dJ+09ps0PsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawMv6A36kfIk4Dl7Zhtuan/eBJ+7ATWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtY2WA1LlDyILYM9NZ795yZvwtYwAKW5wQWsIAFAmABC1jAAhawgAUsYHlOYAELWCAAFrCABSxgAQtYwAKW5wTWWWBNP880EGkbI+1gSFv/Z6n25wcWsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAlYnWGnr0LLBtuBrmcO0g6ExYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgffBjwjbANDQ28C7QafuifW6BBSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMACFrCABSxgAQtYwAIWsICVXdrGToN+6wBon580aNqhBxawgAUsYAELWMACFrCABSxgAQtYwAIWsIAFLGABC1jAAhawgAUsYAELWMC6FSxJApYkAUsSsCQJWJIELEnAkiRgSRKwJAFLkoAlCViSBCxJApYkYEkSsCQJWJKAJU'}},
computed: {imgSrc() {return `data:image/jpg;base64,${this.base64Image}`}},methods: {async copyImage() {try {// 将Base64字符串转换为Uint8Array// 解码Base64字符串const binaryString = atob(this.base64Image);const len = binaryString.length;//二进制字符串转换为一个Uint8Array数组。const bytes = new Uint8Array(len);for (let i = 0; i < len; i++) {bytes[i] = binaryString.charCodeAt(i);}// 将Uint8Array转换为Blob对象const blob = new Blob([bytes], { type: 'image/png' });// 创建URL对象const url = URL.createObjectURL(blob);// 将Blob对象对象复制到剪贴板await navigator.clipboard.write([new ClipboardItem({'image/png': blob})]);console.log('图片已复制到剪贴板');} catch (err) {console.error('复制图片时出错:', err);}}}
}
</script>
3.2代码详解
3.2.1Base64编码的字符串解码为二进制字符串

   atob函数是btoa函数的逆操作。btoa用于将二进制数据转换为Base64编码的字符串,而atob则用于将Base64编码的字符串解码回原始的二进制数据。

javascript"> const binaryString = atob(this.baseSrc);
javascript">this.baseSrc = "SGVsbG8gd29ybGQ=";

举例 

javascript"> const binaryString = atob(this.baseSrc);
//解码后
"Hello world"
3.2.2二进制字符串转换为一个Uint8Array数组
javascript">const binaryString = "01010101";
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {bytes[i] = binaryString.charCodeAt(i);
}
console.log(bytes); // 输出: Uint8Array(8) [48, 49, 48, 49, 48, 49, 48, 49]

创建一个Uint8Array数组:

javascript">const bytes = new Uint8Array(len);

   Uint8Array是一种类型化数组,用于表示8位无符号整数,范围从0到255。

字符转换为对应的ASCII码:

javascript">bytes[i] = binaryString.charCodeAt(i);

        循环中,binaryString.charCodeAt(i)方法用于获取二进制字符串中第i个字符的ASCII码,并将其赋值给bytes数组中的第i个元素。

举例

javascript">const binaryString = "01010101";
const len = binaryString.length;
const bytes = new Uint8Array(len);
for (let i = 0; i < len; i++) {bytes[i] = binaryString.charCodeAt(i);
}
console.log(bytes); // 输出: Uint8Array(8) [48, 49, 48, 49, 48, 49, 48, 49]

 binaryString中的每个字符都被转换为其对应的ASCII码,并存储在bytes数组中。

3.2.3 将Uint8Array转换为Blob对象

         在JavaScript中,Blob(Binary Large Object)对象表示不可变的、原始数据的类文件对象。它通常用于处理二进制数据。

  • 将二进制数据保存到本地文件系统。

  • 将二进制数据上传到服务器。

  • 在网页中显示图像或视频。

Blob构造函数来创建一个Blob对象。Blob构造函数接受两个参数:

  1. 数组:第一个参数是一个数组,数组中的每个元素可以是任意类型的数据,比如字符串、ArrayBuffer、ArrayBufferView、Blob等。这些数据会被合并成一个Blob对象。

  2. 选项对象(可选):第二个参数是一个可选的对象,用于指定Blob的类型。例如,如果创建的是一个图像文件,可以将类型设置为'image/png'

javascript">// 创建一个包含文本数据的Blob对象
const blob = new Blob(['Hello, world!'], { type: 'text/plain' });// 创建一个包含图像数据的Blob对象
const imageBlob = new Blob([imageData], { type: 'image/png' });
 3.2.4创建URL对象
javascript"> // 创建URL对象const url = URL.createObjectURL(blob);

         URL.createObjectURL方法接受一个Blob对象作为参数,并返回一个临时的URL。这个URL指向的是内存中的对象,而不是文件系统中的实际文件。这个URL是唯一的,并且只在创建它的窗口或标签页中有效。

  1. 文件上传和下载:在文件上传或下载的场景中,可以使用Blob对象来表示文件,然后通过URL.createObjectURL生成一个临时的URL,用于在网页中显示或下载文件。

  2. 图像预览在处理图像上传时,可以使用Blob对象和URL.createObjectURL来预览图像,而不需要将图像保存到服务器。

  3. 视频播放:在处理视频文件时,可以使用Blob对象和URL.createObjectURL来在网页中播放视频。

javascript">// 假设有一个Blob对象
const blob = new Blob(['Hello, world!'], { type: 'text/plain' });// 创建一个表示该Blob对象的URL
const url = URL.createObjectURL(blob);// 使用这个URL,例如在<img>标签中显示图像
const img = document.createElement('img');
img.src = url;
document.body.appendChild(img);// 当不再需要这个URL时,应该释放内存
URL.revokeObjectURL(url);
3.2.5Blob对象复制到剪贴板

      将一个图像(以Blob对象的形式)复制到剪贴板。navigator.clipboard.write方法,浏览器提供的一个API,用于将数据写入剪贴板。navigator.clipboard API在大多数现代浏览器中都是可用的,但在某些情况下可能需要用户授权。

  1. Blob对象blob是一个Blob对象,代表一个不可变的、原始数据的类文件对象。在这个例子中,它代表了一个图像文件。

  2. ClipboardItemClipboardItem是一个构造函数,用于创建一个表示剪贴板内容的对象。在这个例子中,它创建了一个包含图像数据(以PNG格式)的剪贴板项。

  3. navigator.clipboard.writenavigator.clipboard.write是一个异步方法,用于将数据写入剪贴板。它接受一个包含一个或多个ClipboardItem对象的数组作为参数。

javascript">async function copyImageToClipboard(blob) {try {await navigator.clipboard.write([new ClipboardItem({'image/png': blob})]);console.log('Image copied to clipboard');} catch (err) {console.error('Failed to copy image to clipboard', err);}
}

http://www.ppmy.cn/news/1556918.html

相关文章

【React前端】大屏适配解决方案从框架结构到实现(超详细)(附代码)

背景 最近公司来了一个大屏的项目&#xff0c;之前没有接触过&#xff0c;因此看了很多方案&#xff0c;总结了一下&#xff0c;然后选择了一种方案去实现&#xff0c;看完这篇文章&#xff0c;只要你有设计稿&#xff0c;拿来就用可以100%高度还原任何场景&#xff01; 方案…

【网络云计算】2024第51周-每日【2024/12/20】小测-理论-周测-解析

文章目录 1. 软件RAID的常用级别和硬件RAID的区别&#xff0c;制作RAID生产环境有哪些注意事项2. 交换机常用的技术有哪些3. NFS服务器如何结合LVM4. 写两个if语句&#xff0c;判断文件和目录是否存在5. 链路聚合和VRRP有哪些区别&#xff1f; 【网络云计算】2024第51周-每日【…

音视频学习(二十七):SRT协议

SRT&#xff08;Secure Reliable Transport&#xff09;是一种开源的网络传输协议&#xff0c;专为实时音视频数据传输设计&#xff0c;具有低延迟、高可靠性和安全性等特点。 核心功能 SRT协议旨在解决实时音视频传输中的网络抖动、丢包、延迟和安全问题&#xff0c;提供以下…

组装一台电脑需要哪些硬件设备?点击了解

组装一台电脑是一个既有趣又实用的过程&#xff0c;我们可以根据自己的需求和预算来定制一台完全符合个人使用习惯的计算机。 一、核心部件 1、中央处理器&#xff08;CPU&#xff09; CPU是计算机的“大脑”&#xff0c;负责执行各种计算任务。它的性能直接影响到计算机的运…

【AI系列】Paddle Speech安装指南

文章目录 环境依赖1. 安装Python1.1 下载Python安装包1.2 安装gcc1.3 安装依赖库1.4 编译和安装Python1.5 配置环境变量 2. 安装PaddlePaddle3. 安装PaddleSpeech4. 运行PaddleSpeech5. 解决常见问题5.1 错误&#xff1a;libssl.so.1.1解决方法&#xff1a; 5.2 错误&#xff1…

建立在商用GPT上的简单高效单细胞表示模型

大规模基因表达数据正被用于单细胞表示模型的预训练。然而&#xff0c;这样的模型需要大量的数据管理和训练。在这里&#xff0c;作者探索了一种更简单的替代方案&#xff1a;使用 GPT-3.5 从单个基因的文本描述中生成基因嵌入&#xff0c;然后通过基因表达量加权gene embeddin…

坑人 C# MySql.Data SDK

一:背景 1. 讲故事 为什么说这东西比较坑人呢?是因为最近一个月接到了两个dump,都反应程序卡死无响应,最后分析下来是因为线程饥饿导致,那什么原因导致的线程饥饿呢?进一步分析发现罪魁祸首是 MySql.Data,这就让人无语了,并且反馈都是升级了MySql.Data驱动引发,接下…

允许某段网络访问Linux服务器上的MariaDB

在Linux服务器上安装了MariaDB&#xff0c;默认情况下&#xff0c;只允许本机访问。在某些特殊的情况下&#xff0c;要允许外部访问。具体操作流程如下&#xff1a; 1 修改服务器配置 vi /etc/my.cnf.d/server.cnf取消下面的注释&#xff0c;以便允许外来的主机访问。 bind-…