vue或react当中canvas实现电子签名组件和使用canvas进行图片压缩

在这里插入图片描述

<template>
  <div>
    <h1>vue3</h1>
    <canvas id="canvasWrite"> 浏览器不支持Canvas,请升级浏览器 </canvas>
    <div>
      <button class="submit" @click="submitWrite">提交签名</button>
      <button class="clear" @click="clearLine">清空签名</button>
    </div>
    <img :src="writeSrc" alt="" />
    <div>
      <button @click="compressImg(writeSrc, 1, setAfterCompression)">
        压缩图片
      </button>
      <div>
        <img :src="afterCompression" alt="" />
      </div>
    </div>
  </div>
</template>

<script>
export default {
  name: "App",
  data() {
    return {
      cvs: "",
      ctx: "",
      writeSrc: "",
      afterCompression: "",
    };
  },
  components: {},
  methods: {
    setAfterCompression(base64Data) {
      this.afterCompression = base64Data;
    },
    // 第二种压缩图片的方法(图片base64,图片类型,压缩比例,回调函数)
    // 该方法只能将图片压缩为为image/jpeg和image/webp两种类型的图片base64
    // 压缩结果存在一定误差  但比第一种方法更加准确
    compressImg(base64, rate = 1, callback) {
      // 声明一个Image对象
      var _img = new Image();
      // 将图片的地址赋予这个Image
      _img.src = base64;
      console.log("base6411", base64);
      // 在图片加载完成后
      _img.onload = function () {
        // 创建canvas标签
        var _canvas = document.createElement("canvas");
        // 设置canvas画布的宽高属性
        // this 指的是当前Image对象
        var w = this.width;
        var h = this.height;
        _canvas.setAttribute("width", w);
        _canvas.setAttribute("height", h);
        // 将图片渲染到canvas画布上 并设置渲染图片的宽高与画布的宽高一致
        _canvas.getContext("2d").drawImage(this, 0, 0, w, h);
        // 将canvas画布转换成base64 但第一个参数 转换后的图片类型只能为image/jpeg或image/webp
        // 根据压缩比例设置第二个参数图片质量(范围0-1)
        var base64 = _canvas.toDataURL("image/gif", rate);
        // 将结果通过回调函数传递给方法的调用者
        callback(base64);
      };
    },
    submitWrite() {
      const aTag = document.createElement("a");
      const base64 = this.cvs.toDataURL("image/gif", 1); //把我们的图片转成base64输出传送给后端;
      this.writeSrc = base64;
      console.log("base64", base64);
      aTag.href = base64;
      aTag.download = "签名";
      // this.getDom("body").appendChild(aTag).click();
      // aTag.remove();
    },
    getDom(selectStr) {
      return document.querySelector(selectStr);
    },
    clearLine() {
      // this.ctx.clearRect(清除的起点x轴,清除的起点y轴,清除画布的宽,清除画布的高);
      console.log("this.ctx", this.ctx);
      console.log("this.ctx.clearRect", this.ctx.clearRect);
      this.ctx.clearRect(0, 0, this.cvs.width, this.cvs.height);
    },
  },
  mounted() {
    let cvs = this.getDom("#canvasWrite");
    let ctx = cvs.getContext("2d");
    this.cvs = cvs;
    this.ctx = ctx;
    // 设置画线线条的粗细
    ctx.lineWidth = 3; //默认值是1
    // 设置线端样式,折角样式
    ctx.lineCap = "round";
    ctx.lineJoin = "round";
    cvs.onmousedown = (e) => {
      // 开始绘制名字
      ctx.beginPath();
      // 将画笔起点设置为当前位置
      ctx.moveTo(e.offsetX, e.offsetY);
      cvs.onmousemove = (ev) => {
        // 画笔跟着鼠标绘制线;
        ctx.lineTo(ev.offsetX, ev.offsetY);
        // 给绘制的线条上色
        // ctx.strokeStyle = "#f00"; //如果不给线条颜色上色默认是看不到绘制的线条的;
        ctx.stroke();
      };
    };
    cvs.onmouseup = () => (cvs.onmousemove = null);
    // this.getDom(".clear").onclick = () => {
    //   console.log("ctx.clearReact", ctx.clearRect);
    //   ctx.clearRect(0, 0, cvs.width, cvs.height);
    // };
  },
};
</script>

<style>
#canvasWrite {
  width: 400;
  height: 260;
  margin: 20px;
  box-shadow: 0px 0px 4px #aaa;
  /* cursor: url('./鼠标形状的icon'),auto; */
  cursor: pointer;
}
.submit {
  margin-left: 20px;
  padding: 5px 15px;
}
.clear {
  margin-left: 20px;
  padding: 5px 15px;
}
</style>

具体压缩可以参考
https://blog.csdn.net/weixin_45092437/article/details/129113469

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

python如何知道你的导包在哪/site-package在哪/anaconda中的模块文件在哪

参考: https://stackoverflow.com/questions/31003994/where-is-site-packages-located-in-a-conda-environment anaconda虚拟环境中的site-package在如下目录&#xff0c;/opt/conda/envs/env_cp37_STAGATE_TF/lib/python3.7/site-packages/。 基于寻找你导包的物理位置在哪…

WPF嵌入外部exe应用程序-使用Winfom控件承载外部程序

使用Winform控件承载外部程序 在WPF中使用Winfom控件添加winform相关的程序集在XAML头中加入对这两个程序集命名空间的引用使用Winform控件效果&#xff1a;问题 在Winfom控件中嵌入exe程序准备Winfrom控件更换父窗体的句柄完整实现代码&#xff1a;实现效果&#xff1a; 问题和…

[java安全]CommonsCollections3.1

文章目录 【java安全】CommonsCollections3.1InvokerTransformerConstantTransformerChainedTransformerTransformedMap如何触发checkSetValue()方法&#xff1f;AnnotationInvocationHandlerpoc利用链 【java安全】CommonsCollections3.1 java开发过程中经常会用到一些库。Ap…

写字楼/办公楼能源管理系统的具体应用 安科瑞 许敏

0 引言 随着社会的进步&#xff0c;我国经济的快速发展&#xff0c;企业的办公环境和方式发生了巨大的变化&#xff0c;专业的写字楼在各大城市遍布林立。写字楼的出现使得各地企业办公集中化、高效化&#xff0c;然而写字楼物业管理的同步发展对于企业服务来说更是一个很大的…

自动化测试(一):网页结构分析与Google翻译2023.7.18爬虫实例

目录 1. 网页分析1.1 静态网页1.2 静态网页的爬取案例1.3 动态网页1.4 Google翻译2023.7.18爬虫实例1.4.1 基于网页分析的Google翻译2023.7.18爬虫实例1.4.2 基于Selenium的Google翻译2023.7.18爬虫实例 1. 网页分析 网页分析即通过检查元素&#xff0c;确定想提取的内容的区域…

【解决】Android Studio打包出现not found for signing config ‘externalOverride‘

问题出现场景 之前我的这个项目在另一台电脑上开发&#xff0c;现在迁移到这台计算机上&#xff0c;出现了key报错的问题&#xff0c;网络上有些说需要在XML中进行配置signature相关的内容&#xff0c;这个感觉比较复杂&#xff0c;本文主要介绍一个简单的解决方法&#xff0c;…

抖音seo源码-源代码开发搭建-开源部署(不加密)

抖音SEO矩阵系统源码开发功能模型是指在抖音平台上提高视频搜索排名的一种算法模型。该功能模型包括多个部分&#xff0c;如内容优化、用户交互、社交化推广等&#xff0c;通过对这些因素的优化和提升&#xff0c;达到提高视频搜索排名的目的。具体实现包括使用关键词、标签等优…

springboot整合jwt

JWT介绍 JWT是JSON Web Token的缩写&#xff0c;即JSON Web令牌&#xff0c;是一种自包含令牌。 是为了在网络应用环境间传递声明而执行的一种基于JSON的开放标准。 JWT的声明一般被用来在身份提供者和服务提供者间传递被认证的用户身份信息&#xff0c;以便于从资源服务器获…

基于C语言设计的足球信息查询系统

完整资料进入【数字空间】查看——baidu搜索"writebug" 需求分析与概要设计 2.1 项目说明 我们小组的选题主要是面向足球爱好者&#xff0c;在普通社交软件的基础之上&#xff0c;围绕足球的主题展开设计&#xff0c;以便于他们能够更好的交流相关的话题&#xff…

SpringAMQP - 消息传输时,如何提高性能?解决 SQL 注入问题?

目录 一、问题背景 二、从消息转化器根源解决问题 1.引入依赖 2.在服务生产者和消费者中都重新定义一个 MessageConverter&#xff0c;注入到 Spring 容器中 一、问题背景 在SpringAMQP的发送方法中&#xff0c;接收消息的类型是Object&#xff0c;也就是说我们可以发送任意…

05-1_Qt 5.9 C++开发指南_Model/View结构基础(基本原理;数据模型;试图组件;代理)

Model/View(模型/视图) 结构是 Qt 中用界面组件显示与编辑数据的一种结构&#xff0c;视图 (View)是显示和编辑数据的界面组件&#xff0c;模型 (Model) 是视图与原始数据之间的接口。Model/View 结构的典型应用是在数据库应用程序中&#xff0c;例如数据库中的一个数据表可以在…

爆肝整理,Postman接口测试-全局变量/接口关联/加密/解密(超细)

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 全局变量和环境变…

GitHub上整理的一些实用的工具

1. Visual Studio Code 简称VScode&#xff0c;是一个轻量且强大的跨平台开源代码编辑器&#xff08;IDE&#xff09;&#xff0c;支持Windows&#xff0c;OS X和Linux。内置JavaScript、TypeScript和Node.js支持&#xff0c;而且拥有丰富的插件生态系统&#xff0c;可通过安装…

谷歌Bard更新:支持中文提问和语音朗读

ChatGPT不断更新功能&#xff0c;从GPT-3到3.5&#xff0c;再到GPT-4&#xff0c;甚至最新的plus版已经支持图像处理和图表生成&#xff0c;而谷歌Bard却自从推出后就一直很安静&#xff0c;没有什么大动作。眼见被ChatGPT、Claude甚至是文心一言抢去了风头&#xff0c;自然心有…

学习Dubbo前你要了解这些

文章目录 Dubbo的发展背景单一应用架构垂直应用架构分布式服务架构流动计算架构 RPCRPC的简单原理 DubboDubbo是什么Dubbo作者Dubbo的发展历程Dubbo架构 Dubbo发音&#xff1a; |ˈdʌbəʊ| Dubbo官方网站&#xff1a;http://dubbo.apache.org/ Dubbo是阿里巴巴开发的&#…

Nginx系列之 一 反向代理

目录 Nginx系列之 一 入门_开着拖拉机回家的博客-CSDN博 一、Nginx概述 二、反向代理 2.1 正向代理 2.2 反向代理 三、反向代理实战 3.1测试服务器 3.2 配置文件说明 3.3 反向代理实战案例一 1、目的 2、具体实现 3.4 反向代理实战案例二 1、目的 2、具体实现 入…

chatglm微调

chatGML 看到 【【官方教程】ChatGLM-6B 微调&#xff1a;P-Tuning&#xff0c;LoRA&#xff0c;Full parameter】 【精准空降到 15:27】 https://www.bilibili.com/video/BV1fd4y1Z7Y5/?share_sourcecopy_web&vd_sourceaa8c13cff97f0454ee41e1f609a655f1&t927 记得看…

深入学习 Redis - 常用数据类型,结构认识

目录 一、Redis数据类型 Redis 数据类型结构简单认识 每个数据类型具体的编码方式 1.string 2.hash 3.list 4.set 5.zset 典中典&#xff1a;记数字&#xff01;&#xff01;&#xff01; 6.查看 key 对应 value 的实际编码方式 如果本文有帮助到你&#xff0c;不…

DataTable数据对比

DataTable数据对比 文章目录 DataTable数据对比前言一、计算DataTable差集结构不同的情况结构相同的情况 二、计算DataTable交集结构不同的情况结构相同的情况 三、计算DataTable的并集合两个DaTable结构相同的情况计算并集 前言 开发中我们经常会出现查询数据库后返回DataTab…

SpringCloud系列(十六)[分布式搜索引擎篇] - DSL 查询及相关性算分的学习 (部分)

在SpringCloud系列&#xff08;十五&#xff09;[分布式搜索引擎篇] - 结合实际应用场景学习并使用 RestClient 客户端 API这篇文章中我们已经对 RestClient 有了初步的了解, 并且已经将一些数据进行了存储, 但是这并不是我们学习 ElasticSearch 的目的, ElasticSearch 最擅长的…