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

Canvas绘制图片和区域

如何使用Canvas在图片上绘制区域?
一. 首先,我们需要初始化三个canvas画布(初始化Canvas)

 

initCanvas() {// 初始化canvas画布let canvasWrap = document.getElementsByClassName("canvas-wrap");this.wrapWidth = canvasWrap[0].clientWidth;this.wrapHeight = canvasWrap[0].clientHeight;this.imgCanvas = document.getElementById("imgCanvas");this.imgCtx = this.imgCanvas.getContext("2d");// 绘制canvasthis.drawCanvas = document.getElementById("drawCanvas");this.drawCtx = this.drawCanvas.getContext("2d");// 保存绘制区域 saveCanvasthis.saveCanvas = document.getElementById("saveCanvas");this.saveCtx = this.saveCanvas.getContext("2d");
}
  1. imgCanvas用于绘制原始图片
  2. drawCanvas用于临时绘制区域
  3. saveCanvas用于保存最终绘制的区域
二. 计算并设置canvas的宽高比例,以适应图片尺寸
initImgCanvas() {// 计算宽高比let ww = this.wrapWidth; // 画布宽度let wh = this.wrapHeight; // 画布高度 let iw = this.imgWidth; // 图片宽度let ih = this.imgHeight; // 图片高度if (iw / ih < ww / wh) {// 以高为主this.ratio = ih / wh;this.canvasHeight = wh;this.canvasWidth = (wh * iw) / ih;} else {// 以宽为主 this.ratio = iw / ww;this.canvasWidth = ww;this.canvasHeight = (ww * ih) / iw;}// 初始化画布大小this.imgCanvas.width = this.canvasWidth;this.imgCanvas.height = this.canvasHeight;this.drawCanvas.width = this.canvasWidth; this.drawCanvas.height = this.canvasHeight;this.saveCanvas.width = this.canvasWidth;this.saveCanvas.height = this.canvasHeight;// 图片加载绘制let img = document.createElement("img");img.src = this.imgUrl;img.onload = () => {console.log("图片已加载");this.imgCtx.drawImage(img, 0, 0, this.canvasWidth, this.canvasHeight);this.renderDatas(); // 渲染原有数据};
}

这里先计算画布和图片的宽高比,根据比例关系决定以宽为主还是以高为主进行等比缩放。然后设置三个canvas的宽高,并在图片加载完成后将其绘制到imgCanvas上。renderDatas函数用于渲染已有的绘制数据。

三. 绘制的主要逻辑 

startDraw() {// 绘制区域if (this.isDrawing) return;this.isDrawing = true;// 绘制逻辑this.drawCanvas.addEventListener("click", this.drawImageClickFn);this.drawCanvas.addEventListener("dblclick", this.drawImageDblClickFn);this.drawCanvas.addEventListener("mousemove", this.drawImageMoveFn);
}

相关文章:

Canvas绘制图片和区域

如何使用Canvas在图片上绘制区域&#xff1f; 一. 首先&#xff0c;我们需要初始化三个canvas画布&#xff08;初始化Canvas&#xff09; initCanvas() {// 初始化canvas画布let canvasWrap document.getElementsByClassName("canvas-wrap");this.wrapWidth canva…...

Day10—Spark SQL基础

Spark SQL介绍 ​ Spark SQL是一个用于结构化数据处理的Spark组件。所谓结构化数据&#xff0c;是指具有Schema信息的数据&#xff0c;例如JSON、Parquet、Avro、CSV格式的数据。与基础的Spark RDD API不同&#xff0c;Spark SQL提供了对结构化数据的查询和计算接口。 Spark …...

开源技术:在线教育系统源码及教育培训APP开发指南

本篇文章&#xff0c;小编将探讨如何利用开源技术开发在线教育系统及教育培训APP&#xff0c;旨在为有志于此的开发者提供全面的指导和实践建议。 一、在线教育系统的基本构架 1.1架构设计 包括前端、后端和数据库三个主要部分。 1.2前端技术 在前端开发中&#xff0c;HTML…...

[C++][设计模式][观察者模式]详细讲解

目录 1.动机2.模式定义3.要点总结4.代码感受1.代码一1.FileSplitter.cpp2.MainForm.cpp 2.代码二1.FileSplitter.cpp2.MainForm.cpp 1.动机 在软件构建过程中&#xff0c;需要为某些对象建立一种“通知依赖关系” 一个对象(目标对象)的状态发生改变&#xff0c;所有的依赖对象…...

Adobe Acrobat 编辑器软件下载安装,Acrobat 轻松编辑和管理各种PDF文件

Adobe Acrobat&#xff0c;它凭借卓越的功能和丰富的工具&#xff0c;为用户提供了一个全面的解决方案&#xff0c;用于查看、创建、编辑和管理各种PDF文件。 作为一款专业的PDF阅读器&#xff0c;Adobe Acrobat能够轻松打开并展示各种格式的PDF文档&#xff0c;无论是文字、图…...

eVTOL飞机:技术挑战、应用机遇和运动的作用

最近&#xff0c;航空业的嗡嗡声围绕着电动空中出租车、空中拼车、无人驾驶航空货物运送等。这些概念都依赖于一类称为eVTOL的飞机&#xff0c;eVTOL是电动垂直起降的缩写。 与直升机类似&#xff0c;但没有噪音和排放&#xff0c;eVTOL可以在不需要简易机场的情况下飞行、悬停…...

【python】flask中如何向https服务器传输信息

【背景】 用flask做一个支持流媒体传输的网页,如何将信息post给流媒体服务器呢? 【方法】 简单例子,视图函数这么写: url = "https://yourip/mytext" headers = {Content-Type:application/octet-stream} @app.route(/,methods=["POST"...

计算机网络 —— 应用层(FTP)

计算机网络 —— 应用层&#xff08;FTP&#xff09; FTP核心特性&#xff1a;运作流程&#xff1a; FTP工作原理主动模式被动模式 我门今天来看应用层的FTP&#xff08;文件传输协议&#xff09; FTP FTP&#xff08;File Transfer Protocol&#xff0c;文件传输协议&#x…...

zookeeper + kafka消息队列

zookeeper kafka 消息队列 一、消息队列简介 1、什么是消息队列 消息队列&#xff08;Message Queue&#xff09;是一种用于跨进程或分布式系统中传递消息的通信机制。消息队列在异步通信、系统解耦、负载均衡和容错方面具有重要作用。 &#xff08;1&#xff09;特性 异步…...

Python高级编程:深度学习基础

Python高级编程:深度学习基础 在前几篇文章中,我们探讨了Python的基础语法、面向对象编程、标准库、第三方库、并发编程、异步编程、网络编程与网络爬虫、数据库操作与ORM、数据分析与数据可视化以及机器学习基础。在这篇文章中,我们将深入探讨Python在深度学习领域的应用。…...

如何从magento1迁移到magento2

m2相较m1 变化可以说非常大&#xff0c;相当于从头到位都改写一遍&#xff0c;更现代化&#xff0c;更优雅。除了数据库表变化不是很大。 主要迁移的内容有&#xff1a; 1&#xff0c;主题 2&#xff0c;插件(自己开发的或者第三方插件) 3&#xff0c;数据库 主题 不能迁移到m…...

【Nginx】Nginx安装及简单使用

https://www.bilibili.com/video/BV1F5411J7vK https://www.kuangstudy.com/bbs/1353634800149213186 https://stonecoding.net/system/nginx/nginx.html https://blog.csdn.net/qq_40492693/article/details/124453090 Nginx 是一个高性能的 HTTP 和反向代理 Web 服务器。其特…...

【Linux系列】find命令使用与用法详解

&#x1f49d;&#x1f49d;&#x1f49d;欢迎来到我的博客&#xff0c;很高兴能够在这里和您见面&#xff01;希望您在这里可以感受到一份轻松愉快的氛围&#xff0c;不仅可以获得有趣的内容和知识&#xff0c;也可以畅所欲言、分享您的想法和见解。 推荐:kwan 的首页,持续学…...

Apple - DNS Service Discovery Programming Guide

本文翻译整理自&#xff1a;DNS Service Discovery Programming Guide&#xff08;更新日期&#xff1a;2013-08-08 https://developer.apple.com/library/archive/documentation/Networking/Conceptual/dns_discovery_api/Introduction.html#//apple_ref/doc/uid/TP30000964 文…...

如何高效地为pip换源:详细操作指南

在Python开发中&#xff0c;pip是我们不可或缺的包管理工具。然而&#xff0c;默认的官方源下载速度较慢&#xff0c;尤其是在国内使用时可能会遇到网络问题。为了提高下载速度&#xff0c;我们可以通过更换国内的镜像源来解决这一问题。本文将详细介绍如何高效地为pip换源&…...

免费ddns工具,快解析DNS解析使用教程

DDNS&#xff08;Dynamic Domain Name Server&#xff09;,中文叫动态域名解析&#xff0c;主要用于没有固定公网ip的网络环境下&#xff0c;使用一个固定的域名&#xff0c;解析动态变化的ip地址&#xff0c;达到远程访问的目的。 众所周知&#xff0c;目前公网ip资源非常紧缺…...

【Vite】控制打包结构

配置 vite.config.json 文件&#xff1a; import { defineConfig } from "vite";export default defineConfig({// ...build: {rollupOptions: {output: {entryFileNames: "js/[name]-[hash].js",chunkFileNames: "js/[name]-[hash].js",assetF…...

Debian Linux安装minikubekubectl

minikube&kubectl minkube用于在本地开发环境中快速搭建一个单节点的Kubernetes集群,还有k3s&#xff0c;k3d&#xff0c;kind都是轻量级的k8skubectl是使用K8s API 与K8s集群的控制面进行通信的命令行工具 这里使用Debian Linux演示&#xff0c;其他系统安装见官网,首先…...

Discuz动漫二次元风格网站模板

1、本模板为门户论坛个人空间形式&#xff0c;其中个人空间模板需要单独购买&#xff0c;点击购买&#xff0c;美化N多默认模板页面 2、全新设计的标签页&#xff0c;标签页帖子图文调用 3、论坛首页&#xff0c;分区下版块帖子论坛首页自动调用&#xff0c;自带分区图片模式与…...

RIP、OSPF、IS-IS学习

文章目录 前言RIP路由信息协议OSPF开放最短路径优先IS-IS 中间系统到中间系统总结 前言 路由协议的种类繁多&#xff0c;每种协议都有其独特的特性、工作原理和适用场景。本文将重点介绍&#xff1a;RIP&#xff08;路由信息协议&#xff09;、OSPF&#xff08;开放最短路径优…...

MPNet:旋转机械轻量化故障诊断模型详解python代码复现

目录 一、问题背景与挑战 二、MPNet核心架构 2.1 多分支特征融合模块(MBFM) 2.2 残差注意力金字塔模块(RAPM) 2.2.1 空间金字塔注意力(SPA) 2.2.2 金字塔残差块(PRBlock) 2.3 分类器设计 三、关键技术突破 3.1 多尺度特征融合 3.2 轻量化设计策略 3.3 抗噪声…...

synchronized 学习

学习源&#xff1a; https://www.bilibili.com/video/BV1aJ411V763?spm_id_from333.788.videopod.episodes&vd_source32e1c41a9370911ab06d12fbc36c4ebc 1.应用场景 不超卖&#xff0c;也要考虑性能问题&#xff08;场景&#xff09; 2.常见面试问题&#xff1a; sync出…...

k8s从入门到放弃之Ingress七层负载

k8s从入门到放弃之Ingress七层负载 在Kubernetes&#xff08;简称K8s&#xff09;中&#xff0c;Ingress是一个API对象&#xff0c;它允许你定义如何从集群外部访问集群内部的服务。Ingress可以提供负载均衡、SSL终结和基于名称的虚拟主机等功能。通过Ingress&#xff0c;你可…...

java调用dll出现unsatisfiedLinkError以及JNA和JNI的区别

UnsatisfiedLinkError 在对接硬件设备中&#xff0c;我们会遇到使用 java 调用 dll文件 的情况&#xff0c;此时大概率出现UnsatisfiedLinkError链接错误&#xff0c;原因可能有如下几种 类名错误包名错误方法名参数错误使用 JNI 协议调用&#xff0c;结果 dll 未实现 JNI 协…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

最新SpringBoot+SpringCloud+Nacos微服务框架分享

文章目录 前言一、服务规划二、架构核心1.cloud的pom2.gateway的异常handler3.gateway的filter4、admin的pom5、admin的登录核心 三、code-helper分享总结 前言 最近有个活蛮赶的&#xff0c;根据Excel列的需求预估的工时直接打骨折&#xff0c;不要问我为什么&#xff0c;主要…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

安卓基础(aar)

重新设置java21的环境&#xff0c;临时设置 $env:JAVA_HOME "D:\Android Studio\jbr" 查看当前环境变量 JAVA_HOME 的值 echo $env:JAVA_HOME 构建ARR文件 ./gradlew :private-lib:assembleRelease 目录是这样的&#xff1a; MyApp/ ├── app/ …...

短视频矩阵系统文案创作功能开发实践,定制化开发

在短视频行业迅猛发展的当下&#xff0c;企业和个人创作者为了扩大影响力、提升传播效果&#xff0c;纷纷采用短视频矩阵运营策略&#xff0c;同时管理多个平台、多个账号的内容发布。然而&#xff0c;频繁的文案创作需求让运营者疲于应对&#xff0c;如何高效产出高质量文案成…...

高防服务器价格高原因分析

高防服务器的价格较高&#xff0c;主要是由于其特殊的防御机制、硬件配置、运营维护等多方面的综合成本。以下从技术、资源和服务三个维度详细解析高防服务器昂贵的原因&#xff1a; 一、硬件与技术投入 大带宽需求 DDoS攻击通过占用大量带宽资源瘫痪目标服务器&#xff0c;因此…...