当前位置: 首页 > article >正文

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

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地址形式
<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 转为 URL
            return new Promise((resolve, reject) => {
                imgElement.onload = async () => {
                    const canvas = document.createElement('canvas'); // 创建 Canvas
                    const ctx = canvas.getContext('2d'); // 获取 Canvas 上下文
                    if (contentType === 'image/gif') {
                        // 处理 GIF,直接使用 GIF Blob
                        const item = new ClipboardItem({ 'image/gif': blob });  // 使用 GIF 格式
                        await navigator.clipboard.write([item]); // 写入剪贴板
                        resolve();
                    } else {
                        // 处理 JPG/JPEG/PNG,转换为 PNG
                        canvas.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 具体代码
<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编码的字符串解码回原始的二进制数据。

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

举例 

 const binaryString = atob(this.baseSrc);
//解码后
"Hello world"
3.2.2二进制字符串转换为一个Uint8Array数组
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数组:

const bytes = new Uint8Array(len);

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

字符转换为对应的ASCII码:

bytes[i] = binaryString.charCodeAt(i);

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

举例

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'

// 创建一个包含文本数据的Blob对象
const blob = new Blob(['Hello, world!'], { type: 'text/plain' });

// 创建一个包含图像数据的Blob对象
const imageBlob = new Blob([imageData], { type: 'image/png' });
 3.2.4创建URL对象
 // 创建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来在网页中播放视频。

// 假设有一个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对象的数组作为参数。

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.kler.cn/a/450938.html

相关文章:

  • 第22天:信息收集-Web应用各语言框架安全组件联动系统数据特征人工分析识别项目
  • 【Rust自学】5.3. struct的方法(Method)
  • 在 Ubuntu 下使用 Tauri 打包 EXE 应用
  • 工业摄像机基于电荷耦合器件的相机
  • Gin-vue-admin(1):环境配置和安装
  • 抢单人机交互「新红利」!哪些细分赛道“多金”?
  • 008 Qt_显示类控件_QLabel
  • 【es6复习笔记】集合Set(13)
  • MongoDB 更新文档
  • Mac M1使用pip3安装报错
  • C++软件设计模式之装饰器模式
  • 创建仓颉编程语言的第一个项目
  • 【2024】Merry Christmas!一起用Rust绘制一颗圣诞树吧
  • GAMES101:现代计算机图形学入门-笔记-11
  • 数据结构与算法Python版 散列与区块链
  • 前端常用算法集合
  • HTTP—01
  • MQTT协议在树莓派上的安全性和性能测试及其在物联网应用中的应用
  • 【网络云计算】2024第52周-每日【2024/12/24】小测-理论实操-解析
  • docker 安装minio
  • SpringBoot的Thymeleaf做一个可自定义合并td的pdf表格
  • LeetCode33题:搜索旋转排序数组(原创)
  • 【VMware虚拟机】安装win10系统教程双机可ping通
  • leetcode hot100回文字符串的链表
  • 帝国CMS:如何去掉帝国CMS登录界面的认证码登录
  • 类OCSP靶场-Kioptrix系列-Kioptrix Level 5(2014)