广告
返回顶部
首页 > 资讯 > 前端开发 > html >怎么实现复制图像
  • 393
分享到

怎么实现复制图像

2024-04-02 19:04:59 393人浏览 安东尼
摘要

这篇文章主要讲解了“怎么实现复制图像”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么实现复制图像”吧!在写了 这个 29.7 K 的剪贴板 js 库有点东

这篇文章主要讲解了“怎么实现复制图像”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么实现复制图像”吧!

在写了 这个 29.7 K 的剪贴板 js 库有点东西! 这篇文章之后,收到了小伙伴提的两个问题:

1.clipboard.js 这个库除了复制文字之外,能复制图像么?

2.clipboard.js 这个库依赖的 document.execCommand api 已被废弃了,以后应该怎么办?

怎么实现复制图像

接下来,本文将围绕上述两个问题展开,不过在看第一个问题之前,我们先来简单介绍一下 剪贴板 ?。

  • 剪贴板(英语:clipboard),有时也称剪切板、剪贴簿、剪贴本。它是一种软件功能,通常由操作系统提供,作用是使用复制和粘贴操作短期存储数据和在文档或应用程序间转移数据。它是图形用户界面(GUI)环境中最常用的功能之一,通常实现为匿名、临时的数据缓冲区,可以被环境内的大部分或所有程序使用编程接口访问。——  维基百科

通过以上的描述我们可以知道,剪贴板架起了一座桥梁,使得在各种应用程序之间,传递和共享信息成为可能。然而美中不足的是,剪贴板只能保留一份数据,每当新的数据传入,旧的便会被覆盖。

了解完 剪贴板 ? 的概念和作用之后,我们马上来看一下第一个问题:clipboard.js 这个库除了复制文字之外,能复制图像么?

一、clipboard.js 能否复制图像?

clipboard.js 是一个用于将 文本 复制到剪贴板的 JS 库。没有使用  Flash,没有使用任何框架,开启 gzipped 压缩后仅仅只有 3kb。

怎么实现复制图像

(图片来源:https://clipboardjs.com/#example-text)

当你看到 “A modern approach to copy text to clipboard”  这个描述,你是不是已经知道答案了。那么实际的情况是怎样呢?下面我们来动手验证一下。在 这个 29.7 K 的剪贴板 JS 库有点东西!  这篇文章中,阿宝哥介绍了在实例化 ClipboardJS 对象时,可以通过 options 对象的 target 属性来设置复制的目标:

// Https://GitHub.com/zenorocha/clipboard.js/blob/master/demo/function-target.html let clipboard = new ClipboardJS('.btn', {   target: function() {     return document.querySelector('div');   } });

利用 clipboard.js 的这个特性,我们可以定义以下 HTML 结构:

<div id="container">    <img src="http://cdn.semlinker.com/abao.png" width="80" height="80"/>    <p>大家好,我是阿宝哥</p> </div> <button class="btn">复制</button>

然后在实例化 ClipboardJS 对象时设置复制的目标是 #container 元素:

const clipboard = new ClipboardJS(".btn", {   target: function () {     return document.querySelector("#container");   } });

之后,我们点击页面中的 复制 按钮,对应的效果如下图所示:

 怎么实现复制图像

观察上图可知,页面中的图像和文本都已经被复制了。对于文本来说,大家应该都很清楚。而对于图像来说,到底复制了什么?我们又该如何获取已复制的内容呢?针对这个问题,我们可以利用  HTMLElement 对象上的 onpaste 属性或者监听元素上的 paste 事件。

这里我们通过设置 document 对象的 onpaste 属性,来打印一下粘贴事件对应的事件对象:

document.onpaste = function (e) {   console.dir(e); }

当我们点击 复制 按钮,然后在页面执行 粘贴 操作后,控制台会打印出以下内容:

怎么实现复制图像

通过上图可知,在 ClipboardEvent 对象中含有一个 clipboardData 属性,该属性包含了与剪贴板相关联的数据。详细分析了  clipboardData 属性之后,我们发现已复制的图像和普通文本被封装为 DataTransferItem 对象。

为了更方便地分析 DataTransferItem 对象,阿宝哥重新更新了 document 对象的 onpaste属性:

怎么实现复制图像

在上图中,我们可以清楚的看到 DataTransferItem 对象上含有 kind 和 type 属性分别用于表示数据项的类型(string 或  file)及数据对应的 MIME 类型。利用 DataTransferItem 对象提供的 getAsString  方法,我们可以获取该对象中保存的数据:

怎么实现复制图像

相信看完以上的输出结果,小伙伴们就很清楚第一个问题的答案了。那么如果想要复制图像的话,应该如何实现呢?其实这个问题的答案与小伙伴提的第二个问题的答案是一样的,我们可以利用  Clipboard API 来实现复制图像的问题及解决 document.execCommand API 已被废弃的问题。

接下来,我们的目标就是实现复制图像的功能了,因为要利用到 Clipboard API,所以阿宝哥先来介绍一下该 API。

二、Clipboard API 简介

Clipboard 接口实现了 Clipboard API,如果用户授予了相应的权限,就能提供系统剪贴板的读写访问。在  WEB 应用程序中,Clipboard API 可用于实现剪切、复制和粘贴功能。该 API 用于取代通过 document.execCommand API  来实现剪贴板的操作。

在实际项目中,我们不需要手动创建 Clipboard 对象,而是通过 navigator.clipboard来获取 Clipboard 对象:

 怎么实现复制图像

在获取 Clipboard 对象之后,我们就可以利用该对象提供的 API 来访问剪贴板,比如:

navigator.clipboard.readText().then(   clipText => document.querySelector(".editor").innerText = clipText);

以上代码将 HTML 中含有 .editor  类的第一个元素的内容替换为剪贴板的内容。如果剪贴板为空,或者不包含任何文本,则元素的内容将被清空。这是因为在剪贴板为空或者不包含文本时,readText  方法会返回一个空字符串

在继续介绍 Clipboard API 之前,我们先来看一下 Navigator API: clipboard 的兼容性:

怎么实现复制图像

(图片来源:https://caniuse.com/mdn-api_navigator_clipboard)

异步剪贴板 API 是一个相对较新的 API,浏览器仍在逐渐实现它。由于潜在的安全问题和技术复杂性,大多数浏览器正在逐步集成这个  API。对于浏览器扩展来说,你可以请求 clipboardRead 和 clipboardWrite 权限以使用 clipboard.readText() 和  clipboard.writeText()。

好的,接下来阿宝哥来演示一下如何使用 clipboard 对象提供的 API 来操作剪贴板,以下示例的运行环境是 Chrome  87.0.4280.88。

三、将数据写入到剪贴板

3.1 writeText()

writeText 方法可以把指定的字符串写入到系统的剪贴板中,调用该方法后会返回一个 Promise 对象:

<button onclick="copyPageUrl()">拷贝当前页面地址</button> <script>    async function copyPageUrl() {      try {        await navigator.clipboard.writeText(location.href);        console.log("页面地址已经被拷贝到剪贴板中");      } catch (err) {        console.error("页面地址拷贝失败: ", err);      }   } </script>

对于上述代码,当用户点击 拷贝当前页面地址 按钮时,将会把当前的页面地址拷贝到剪贴板中。

3.2 write()

write 方法除了支持文本数据之外,还支持将图像数据写入到剪贴板,调用该方法后会返回一个 Promise 对象。

<button onclick="copyPageUrl()">拷贝当前页面地址</button> <script>    async function copyPageUrl() {      const text = new Blob([location.href], {type: 'text/plain'});      try {        await navigator.clipboard.write(          new ClipboardItem({            "text/plain": text,          }),        );        console.log("页面地址已经被拷贝到剪贴板中");      } catch (err) {        console.error("页面地址拷贝失败: ", err);      }   } </script>

在以上代码中,我们先通过 Blob API 创建 Blob 对象,然后使用该 Blob 对象来构造 ClipboardItem 对象,最后再通过  write 方法把数据写入到剪贴板。介绍完如何将数据写入到剪贴板,下面我们来介绍如何从剪贴板中读取数据。

四、从剪贴板中读取数据

4.1 readText()

readText 方法用于读取剪贴板中的文本内容,调用该方法后会返回一个 Promise 对象:

<button onclick="getClipboardContents()">读取剪贴板中的文本</button> <script>    async function getClipboardContents() {      try {        const text = await navigator.clipboard.readText();        console.log("已读取剪贴板中的内容:", text);      } catch (err) {        console.error("读取剪贴板内容失败: ", err);      }    } </script>

对于上述代码,当用户点击 读取剪贴板中的文本 按钮时,如果当前剪贴板含有文本内容,则会读取剪贴板中的文本内容。

4.2 read()

read 方法除了支持读取文本数据之外,还支持读取剪贴板中的图像数据,调用该方法后会返回一个 Promise 对象:

<button onclick="getClipboardContents()">读取剪贴板中的内容</button> <script> async function getClipboardContents() {   try {     const clipboardItems = await navigator.clipboard.read();     for (const clipboardItem of clipboardItems) {       for (const type of clipboardItem.types) {         const blob = await clipboardItem.getType(type);         console.log("已读取剪贴板中的内容:", await blob.text());       }     }   } catch (err) {       console.error("读取剪贴板内容失败: ", err);     }   } </script>

对于上述代码,当用户点击 读取剪贴板中的内容 按钮时,则会开始读取剪贴板中的内容。到这里 clipboard 对象中涉及的 4 个  API,阿宝哥都已经介绍完了,最后我们来看一下如何实现复制图像的功能。

五、实现复制图像的功能

在最后的这个示例中,阿宝哥将跟大家一步步实现复制图像的核心功能,除了复制图像之外,还会同时支持复制文本。在看具体代码前,我们先来看一下实际的效果:

怎么实现复制图像

在上图对应的网页中,我们先点击 复制 按钮,则图像和文本都会被选中。之后,我们在点击 粘贴  按钮,则控制台会输出从剪贴板中读取的实际内容。在分析具体的实现方式前,我们先来看一下对应的页面结构:

<div id="container">    <img src="http://cdn.semlinker.com/abao.png" width="80" height="80" />    <p>大家好,我是阿宝哥</p> </div> <button onclick="writeDataToClipboard()">复制</button> <button onclick="readDataFromClipboard()">粘贴</button>

上面的页面结构很简单,下一步我们来逐步分析一下以上功能的实现过程。

5.1 请求剪贴板写权限

默认情况下,会为当前的激活的页面自动授予剪贴板的写入权限。出于安全方面考虑,这里我们还是主动向用户请求剪贴板的写入权限:

async function askWritePermission() {   try {     const { state } = await navigator.permissions.query({       name: "clipboard-write",     });       return state === "granted";   } catch (error) {       return false;   } }

5.2 往剪贴板写入图像和普通文本数据

要往剪贴板写入图像数据,我们就需要使用 navigator.clipboard 对象提供的 write  方法。如果要写入图像数据,我们就需要获取该图像对应的 Blob 对象,这里我们可以通过 fetch API 从网络上获取图像对应的响应对象并把它转化成 Blob  对象,具体实现方式如下:

async function createImageBlob(url) {   const response = await fetch(url);   return await response.blob(); }

而对于普通文本来说,只需要使用前面介绍的 Blob API 就可以把普通文本转换为 Blob 对象:

function createTextBlob(text) {   return new Blob([text], { type: "text/plain" }); }

在创建完图像和普通文本对应的 Blob 对象之后,我们就可以利用它们来创建 ClipboardItem 对象,然后再调用 write  方法把这些数据写入到剪贴板中,对应的代码如下所示:

async function writeDataToClipboard() {   if (askWritePermission()) {     if (navigator.clipboard && navigator.clipboard.write) {         const textBlob = createTextBlob("大家好,我是阿宝哥");         const imageBlob = await createImageBlob(           "http://cdn.semlinker.com/abao.png"         );         try {           const item = new ClipboardItem({             [textBlob.type]: textBlob,             [imageBlob.type]: imageBlob,           });           select(document.querySelector("#container"));           await navigator.clipboard.write([item]);           console.log("文本和图像复制成功");         } catch (error) {           console.error("文本和图像复制失败", error);         }       }    } }

在以上代码中,使用了一个 select 方法,该方法用于实现选择的效果,对应的代码如下所示:

function select(element) {   const selection = window.getSelection();   const range = document.createRange();   range.selectnodeContents(element);   selection.removeAllRanges();   selection.addRange(range); }

通过 writeDataToClipboard 方法,我们已经把图像和普通文本数据写入剪贴板了。下面我们来使用 navigator.clipboard  对象提供的 read 方法,来读取已写入的数据。如果你需要读取剪贴板的数据,则需要向用户请求 clipboard-read 权限。

5.3 请求剪贴板读取权限

这里我们定义了一个 askReadPermission 函数来向用户请求剪贴板读取权限:

async function askReadPermission() {   try {     const { state } = await navigator.permissions.query({       name: "clipboard-read",     });     return state === "granted";   } catch (error) {     return false;   } }

当调用 askReadPermission 方法后,将会向当前用户请求剪贴板读取权限,对应的效果如下图所示:

怎么实现复制图像

5.4 读取剪贴板中已写入的数据

创建好 askReadPermission 函数,我们就可以利用之前介绍的 navigator.clipboard.read  方法来读取剪贴板的数据了:

async function readDataFromClipboard() {   if (askReadPermission()) {     if (navigator.clipboard && navigator.clipboard.read) {       try {         const clipboardItems = await navigator.clipboard.read();         for (const clipboardItem of clipboardItems) {           console.dir(clipboardItem);           for (const type of clipboardItem.types) {             const blob = await clipboardItem.getType(type);             console.log("已读取剪贴板中的内容:", await blob.text());           }         }       } catch (err) {          console.error("读取剪贴板内容失败: ", err);       }      }    } }

其实,除了点击 粘贴 按钮之外,我们还可以通过监听 paste 事件来读取剪贴板中的数据。需要注意的是,如果当前的浏览器不支持异步 Clipboard  API,我们可以通过 clipboardData.getData 方法来读取剪贴板中的文本数据:

document.addEventListener('paste', async (e) => {   e.preventDefault();   let text;   if (navigator.clipboard) {     text = await navigator.clipboard.readText();   } else {     text = e.clipboardData.getData('text/plain');   }   console.log('已获取的文本数据: ', text); });

而对于图像数据,则可以通过以下方式进行读取:

const IMAGE_MIME_REGEX = /^image\/(p?jpeg|gif|png)$/i;  document.addEventListener("paste", async (e) => {   e.preventDefault();   if (navigator.clipboard) {     let clipboardItems = await navigator.clipboard.read();     for (const clipboardItem of clipboardItems) {        for (const type of clipboardItem.types) {          if (IMAGE_MIME_REGEX.test(type)) {            const blob = await clipboardItem.getType(type);            loadImage(blob);            return;          }         }      }    } else {        const items = e.clipboardData.items;        for (let i = 0; i < items.length; i++) {          if (IMAGE_MIME_REGEX.test(items[i].type)) {          loadImage(items[i].getAsFile());          return;        }     }   } });

以上代码中的 loadImage 方法用于实现把复制的图片插入到当前选区已选择的区域中,对应的代码如下:

function loadImage(file) {   const reader = new FileReader();   reader.onload = function (e) {     let img = document.createElement("img");     img.src = e.target.result;      let range = window.getSelection().getRangeAt(0);     range.deleteContents();     range.insertNode(img);   };   reader.readAsDataURL(file); }

感谢各位的阅读,以上就是“怎么实现复制图像”的内容了,经过本文的学习后,相信大家对怎么实现复制图像这一问题有了更深刻的体会,具体使用情况还需要大家实践验证。这里是编程网,小编将为大家推送更多相关知识点的文章,欢迎关注!

--结束END--

本文标题: 怎么实现复制图像

本文链接: https://www.lsjlt.com/news/84162.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 怎么实现复制图像
    这篇文章主要讲解了“怎么实现复制图像”,文中的讲解内容简单清晰,易于学习与理解,下面请大家跟着小编的思路慢慢深入,一起来研究和学习“怎么实现复制图像”吧!在写了 这个 29.7 K 的剪贴板 JS 库有点东...
    99+
    2022-10-19
  • matlab怎么绘制复杂函数图像
    在Matlab中,可以使用`ezplot`函数来绘制复杂函数的图像。`ezplot`函数的语法是:```matlabezplot(f...
    99+
    2023-09-05
    matlab
  • 怎么在Android中实现绘制扭曲图像
    怎么在Android中实现绘制扭曲图像?相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。定义基本变量:MyView是用于显示扭曲的图像的自定义view,angle是圆形轨迹的当前角...
    99+
    2023-05-30
    android
  • OpenCV图像算法怎么实现图像切分图像合并
    本篇内容介绍了“OpenCV图像算法怎么实现图像切分图像合并”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!将一张图片切分成多个小图片并将小图...
    99+
    2023-06-30
  • OpenCV 图像绘制的实现
    目录+直线绘制圆形绘制矩形绘制椭圆型绘制自定义形状绘制文本+直线绘制 参数解析:(图像矩阵,直线起始坐标, 直线终止坐标、颜色、线条厚度) import cv2 import n...
    99+
    2022-11-12
  • vue怎么实现复制文字和图片
    本篇内容主要讲解“vue怎么实现复制文字和图片”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“vue怎么实现复制文字和图片”吧!document.execCommand('copy'...
    99+
    2023-07-05
  • PyTorch怎么实现图像识别
    这篇文章主要介绍“PyTorch怎么实现图像识别”,在日常操作中,相信很多人在PyTorch怎么实现图像识别问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”PyTorch怎么实现图像识别”的疑惑有所帮助!接下来...
    99+
    2023-06-29
  • Python怎么实现图像分割
    本篇内容介绍了“Python怎么实现图像分割”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!方法一import randomimpo...
    99+
    2023-06-29
  • C++OpenCV实现图像修复功能
    目录前言一、OpenCV inpaint二、源码三、效果显示前言 本文将使用OpenCV C++ 对有瑕疵的图像进行修复。OpenCV 提供了inpaint API可进行图像修复。 ...
    99+
    2022-11-12
  • C++实现PatchMatch图像修复算法
    PatchMatch算法出自Barnes的论文 PatchMatch: A Randomized Correspondence Algorithm for Structural I...
    99+
    2022-11-12
  • Android基于OpenCV实现图像修复
    目录图像修复API操作效果源码图像修复 实际应用中,图像常常容易受损,如存在污渍的镜头、旧照片的划痕、人为的涂画(比如马赛克),亦或是图像本身的损坏。将受到损坏的图像尽可能还原成原...
    99+
    2022-11-12
  • python opencv图像旋转怎么实现
    要在Python中使用OpenCV实现图像旋转,可以使用OpenCV中的getRotationMatrix2D和warpAffine...
    99+
    2023-10-21
    python
  • pytorch transforms图像增强怎么实现
    这篇文章主要介绍“pytorch transforms图像增强怎么实现”的相关知识,小编通过实际案例向大家展示操作过程,操作方法简单快捷,实用性强,希望这篇“pytorch transforms图像增强怎么实现”文章能帮...
    99+
    2023-07-05
  • Java数字图像处理之图像灰度处理怎么实现
    本篇内容介绍了“Java数字图像处理之图像灰度处理怎么实现”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!一、简介图像灰度化处理可以作为图像处...
    99+
    2023-07-02
  • 怎么用Python的Pyecharts绘制图像
    本篇内容介绍了“怎么用Python的Pyecharts绘制图像”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!前言:Echarts 是百度开源...
    99+
    2023-06-29
  • vue实现复制文字复制图片实例详解
    目录正文方法复制文本复制图片正文 复制文字和图片是我们经常会使用到的需求,我们这篇文章主要介绍使用navigator.clipboard.write()来实现复制文字和图片。不过这...
    99+
    2023-02-23
    vue复制文字图片 vue 复制
  • c++图像识别功能怎么实现
    要实现C++图像识别功能,你可以使用图像处理库和机器学习库来完成。以下是一种可能的实现方法: 安装和配置OpenCV库:Open...
    99+
    2023-10-24
    c++
  • python图像降噪算法怎么实现
    在Python中,可以使用OpenCV库来实现图像降噪算法。以下是一种常见的降噪算法——中值滤波算法的实现示例: import cv...
    99+
    2023-10-27
    python
  • CSS怎么实现背景图像透明
    这篇文章主要为大家展示了“CSS怎么实现背景图像透明”,内容简而易懂,条理清晰,希望能够帮助大家解决疑惑,下面让小编带领大家一起研究并学习一下“CSS怎么实现背景图像透明”这篇文章吧。   首先,我们来看...
    99+
    2022-10-19
  • Python中OpenCV图像平移怎么实现
    小编给大家分享一下Python中OpenCV图像平移怎么实现,相信大部分人都还不怎么了解,因此分享这篇文章给大家参考一下,希望大家阅读完这篇文章后大有收获,下面让我们一起去了解一下吧!每次学习新东西的时候,橡皮擦都是去海量检索,然后找到适合...
    99+
    2023-06-15
软考高级职称资格查询
推荐阅读
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作