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

js使用canvas实现图片鼠标滚轮放大缩小拖拽预览,显示像素坐标,显示像素值

html代码

todo 实现画矩形框,圆形roi

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Canvas Image Viewer</title>
<style>canvas {border: 1px solid black;}
</style>
</head>
<body>
<div><button id="loadImageButton">Load Image</button>
</div>
<canvas id="mainCanvas" width="900" height="800"></canvas><div><span>坐标</span><span id="imageXY"></span><div><span id="imagePix"></span></div>
</div><script>const canvas = document.getElementById('mainCanvas');const ctx = canvas.getContext('2d');ctx.imageSmoothingEnabled = false;let imageObj = new Image();let imageWidth;let imageHeight;let scale = 1;let offsetX = 0;let offsetY = 0;let pixdata;canvas.addEventListener('mousedown', mouseDownListener);canvas.addEventListener('mouseup', mouseUpListener);canvas.addEventListener('mousemove', mouseMoveListener);canvas.addEventListener('mousewheel', mouseWheelListener);document.getElementById('loadImageButton').addEventListener('click', loadImage);function initPixData(image){const canvasHide = document.createElement('canvas');const context = canvasHide.getContext('2d');canvasHide.width = image.width;canvasHide.height = image.height;context.drawImage(image, 0, 0);const imageData = context.getImageData(0, 0, image.width, image.height);pixdata = imageData.data;console.log(pixdata)}function getPixelValue(x, y) {let pixelValue;if (pixdata.length === 4) {pixelValue = {red: pixel[0],green: pixel[1],blue: pixel[2],alpha: pixel[3]};} else if (ipixdata.length === 1) {pixelValue = {gray: pixel[0]};} else {throw new Error('Unsupported image format');}return pixelValue;}function loadImage() {const input = document.createElement('input');input.type = 'file';input.accept = 'image/*';input.click();input.onchange = e => {const file = e.target.files[0];const reader = new FileReader();reader.onload = readerEvent => {const url = readerEvent.target.result;imageObj.src = url;};reader.readAsDataURL(file);};}let isDragging = false;let lastX;let lastY;function mouseDownListener(e) {let rect = canvas.getBoundingClientRect();isDragging = true;lastX = e.clientX - rect.left;lastY = e.clientY - rect.top;}function mouseUpListener(e) {isDragging = false;}function mouseMoveListener(e) {if (isDragging) {let rect = canvas.getBoundingClientRect();offsetX += (e.clientX - rect.left) - lastX;offsetY += (e.clientY - rect.top) - lastY;lastX = e.clientX - rect.left;lastY = e.clientY - rect.top;ctx.clearRect(0, 0, canvas.width, canvas.height);drawImage();}showImageXY(e);}function mouseWheelListener(e) {let delta = Math.max(-1, Math.min(1, (e.wheelDelta || -e.detail)));if (scale > 0.1 && scale < 10 && delta < 0) {scale *= 0.9;}if (scale > 0.1 && scale < 10 && delta > 0) {scale *= 1.1;}ctx.clearRect(0, 0, canvas.width, canvas.height);drawImage();}function createBlock(a, b, r) {let rect = canvas.getBoundingClientRect();let canvasX = (a * scale) + offsetX + rect.left;let canvasY = (b * scale) + offsetY + rect.top;let radius=r*scale;ctx.beginPath();ctx.fillStyle = 'red';ctx.arc(canvasX, canvasY, radius, 0, Math.PI * 2);ctx.fill();}function drawImage() {ctx.drawImage(imageObj, offsetX, offsetY,imageWidth * scale,imageHeight * scale);createBlock(200,200,200)}//计算当前鼠标坐标对应的图片里的像素坐标function showImageXY(e) {let rect = canvas.getBoundingClientRect();let x=(e.clientX - rect.left- offsetX)/scalelet y=(e.clientY- rect.top - offsetY)/scalex=Math.round(x)y=Math.round(y)if(x<0 || x>imageWidth){x="-"}if(y<0 || y>imageHeight){y="-"}if(!(x=='-'|| y=='-')){showImagePixVal(x,y);}document.getElementById("imageXY").innerText = `x=${x} y=${y} xInCanvas=${offsetX} yInCanvas=${offsetY} width=${imageWidth} height=${imageHeight}`;}function showImagePixVal(x,y){let idx=((y * (imageWidth * 4)) + (x * 4));if(pixdata){let r=pixdata[idx]let g=pixdata[idx+1]let b=pixdata[idx+2]let a=pixdata[idx+3]document.getElementById("imagePix").innerText = `r=${r} g=${g} b=${b} a=${a}`;}}imageObj.onload = () => {imageWidth = imageObj.width;imageHeight = imageObj.height;drawImage();initPixData(imageObj);}
</script>
</body>
</html>

相关文章:

js使用canvas实现图片鼠标滚轮放大缩小拖拽预览,显示像素坐标,显示像素值

html代码 todo 实现画矩形框&#xff0c;圆形roi <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title&…...

ArrayList 源码解析和设计思路

ArrayList 一、继承体系二、接口继承三、标记接口四、设计目的五、框架总体结构六、工作原理七、创建List对象初始化&#xff1f;还是add()添加元素初始化?七、add(E e)添加元素八、remove&#xff08;int index&#xff09;删除元素八、线程安全问题 一、继承体系 ArrayLis…...

Win10系统使用IIS服务搭建WebDAV网站结合内网穿透公网访问本地文件

文章目录 推荐1. 安装IIS必要WebDav组件2. 客户端测试3. cpolar内网穿透3.1 打开Web-UI管理界面3.2 创建隧道3.3 查看在线隧道列表3.4 浏览器访问测试 4. 安装Raidrive客户端4.1 连接WebDav服务器4.2 连接成功4.2 连接成功总结&#xff1a; 推荐 前些天发现了一个巨牛的人工智能…...

AWTK 开源串口屏的配置文件

配置文件 每个 HMI 应用程序都需要一个配置文件&#xff0c;用于配置 HMI 的基本信息、服务、持久化、告警信息、历史数据等。 文件位置 design/default/data/settings.json基本配置 name - 名称&#xff08;必须配置&#xff0c;只能用字母、数字、下划线&#xff09; se…...

Spring、SpringMVC、Spring Boot常见注解有哪些?不要混淆了哦

Spring、SpringMVC、Spring Boot常见注解 一、Spring 注解说明Component、Controller、Service、Repository使用在类上用于实例化BeanAutowired使用在字段上用于根据类型依赖注入Qualifier结合Autowired一起使用用于根据名称进行依赖注入Scope标注Bean的作用范围Configuratio…...

在notion里面实现四象限清单

四象限清单是一种时间管理工具&#xff0c;旨在帮助人们根据任务的重要性和紧急性来优先排序他们的工作。这个概念最早由德怀特艾森豪威尔提出&#xff0c;后来又被史蒂芬柯维在他的著作《高效能人士的七个习惯》中进一步普及。四象限清单将任务分为四个类别&#xff1a; 第一…...

【linux】搜索所有目录和子目录下的包含.git的文件并删除

一、linux命令搜索所有目录和子目录下的包含.git的文件 在Linux系统中&#xff0c;要搜索所有目录和子目录下的包含.git的文件&#xff0c;可以使用find命令。find命令允许指定路径、表达式和操作来查找文件。 以下是使用find命令搜索包含.git的文件的方法&#xff1a; 1. 基…...

三、传输层拥塞控制、差错控制

3.1 概述和传输层服务 传输服务和协议&#xff1a; 为运行在不同主机上的应用进程提供逻辑通信&#xff1b; 传输协议运行在端系统-发送方:将应用层的报文分成报文段&#xff0c;然后传递给网络层&#xff1b;接收方&#xff1a;将报文段重组成报文&#xff0c;然后传递给应用…...

主流电商平台数据大规模数据采集接口的实现:电商API接口接入方案和电商数据采集现状

现实问题 1、您是否需要经常统计关注的品牌、产品、平台、卖家的电商数据&#xff0c;包括销量、评价量、收藏量、预售量、运费、赠品和促销信息&#xff0c;手头上没有稳定的数据源&#xff1f; 2、您是否经常需要统计授权卖家和非授权卖家的销售、动销占比&#xff0c;分析…...

Python电梯楼层数字识别

程序示例精选 Python电梯楼层数字识别 如需安装运行环境或远程调试&#xff0c;见文章底部个人QQ名片&#xff0c;由专业技术人员远程协助&#xff01; 前言 这篇博客针对《Python电梯楼层数字识别》编写代码&#xff0c;代码整洁&#xff0c;规则&#xff0c;易读。 学习与应…...

Linux学习:基础开发工具的使用(1)

目录 1. Linux软件包管理器&#xff1a;yum工具1.1 yum是什么&#xff08;软件商城&#xff09;1.2 yum的使用1.3 yum的背景生态 2. 项目开发与集成开发环境3. vim编辑器3.1 vim编辑器的常见模式与模式切换3.3 vim编辑器的使用3.3.1 命令模式下的常见命令&#xff1a;3.3.2 vim…...

在idea中配置tomcat服务器,然后部署一个项日

1.下载tomcat Tomcat下载 点击右边的tomcat8 找到zip点击下载 下载完&#xff0c;解压到你想放置的路径下 2.配置环境变量 打开设置找到高级系统设置点击环境变量 点击新建&#xff0c;变量名输入&#xff1a;CATALINA_HOME&#xff0c;变量值就是Tomcat的安装路径&#x…...

C语言例:设 int a=11; 则表达式 a+=a-=a*a 的值

注&#xff1a;软件为VC6.0 代码如下&#xff1a; #include<stdio.h> int main(void) {int a11, b;b (aa-a*a); //a*a121 -->a-121结果为a-110 -->a-110结果为a-220printf("表达式aa-a*a 的值为&#xff1a; %d\n",b);return 0; } //优先级&#x…...

C++ 中的虚函数和多态性

C 是一种高级编程语言&#xff0c;它具有面向对象编程的特性。在 C 中&#xff0c;虚函数和多态性是非常重要的概念&#xff0c;它们使得继承关系更加灵活和强大。 虚函数是在基类中声明为虚函数的成员函数&#xff0c;其作用是在运行时动态绑定函数的调用。当在派生类中重写基…...

叶顺舟:手机SoC音频趋势洞察与端侧AI技术探讨 | 演讲嘉宾公布

后续将陆续揭秘更多演讲嘉宾&#xff01; 请持续关注&#xff01; 2024中国国际音频产业大会(GAS)将于2024年3.27 - 28日在上海张江科学会堂举办。大会将以“音无界&#xff0c;未来&#xff08;Audio&#xff0c; Future&#xff09;”为主题。大会由中国电子音响行业协会、上…...

SpringBoot之yml与properties配置文件格式的区别

概念: SpringBoot支持两种格式的配置文件,一种是yml,而另一种就是properties,默认的文件名为application.yml或者.properties 为什么有了properties之后还要有yml呢? 因为properties配置文件存在数据冗余性,在properties配置文件中一切配置都需要从头写到为, 并且Key不能重复,…...

【递归搜索回溯专栏】专题二:二叉树中的深搜----二叉树剪枝

本专栏内容为&#xff1a;递归&#xff0c;搜索与回溯算法专栏。 通过本专栏的深入学习&#xff0c;你可以了解并掌握算法。 &#x1f493;博主csdn个人主页&#xff1a;小小unicorn ⏩专栏分类&#xff1a;递归搜索回溯专栏 &#x1f69a;代码仓库&#xff1a;小小unicorn的代…...

Django实现登录注册

Django实现登录注册 目录 Django实现登录注册配置路由首页注册前端&#xff1a;后端&#xff1a; 登录前端&#xff1a;后端&#xff1a;验证码部分逻辑 配置路由 首先分发路由[User,Blog,Article] from django.contrib import admin from django.urls import path from Blog…...

Python实战:NumPy数组与矩阵操作入门

NumPy是Python数据科学领域中不可或缺的库之一&#xff0c;它提供了一个强大的N维数组对象和一系列用于操作这些数组的函数。本文将详细介绍NumPy数组与矩阵的基础知识&#xff0c;包括数组的创建、操作、切片、索引、以及矩阵的运算等。 1. 引言 在Python数据科学领域&#…...

2024.2.26校招 实习 内推 面经

绿*泡*泡VX&#xff1a; neituijunsir 交流*裙 &#xff0c;内推/实习/校招汇总表格 1、校招&实习 |美团2024年春季校园招聘全球启动&#xff08;内推&#xff09; 校招&实习 |美团2024年春季校园招聘全球启动&#xff08;内推&#xff09; 2、校招 | 江淮汽车2024…...

7.4.分块查找

一.分块查找的算法思想&#xff1a; 1.实例&#xff1a; 以上述图片的顺序表为例&#xff0c; 该顺序表的数据元素从整体来看是乱序的&#xff0c;但如果把这些数据元素分成一块一块的小区间&#xff0c; 第一个区间[0,1]索引上的数据元素都是小于等于10的&#xff0c; 第二…...

Spring Boot 实现流式响应(兼容 2.7.x)

在实际开发中&#xff0c;我们可能会遇到一些流式数据处理的场景&#xff0c;比如接收来自上游接口的 Server-Sent Events&#xff08;SSE&#xff09; 或 流式 JSON 内容&#xff0c;并将其原样中转给前端页面或客户端。这种情况下&#xff0c;传统的 RestTemplate 缓存机制会…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

2021-03-15 iview一些问题

1.iview 在使用tree组件时&#xff0c;发现没有set类的方法&#xff0c;只有get&#xff0c;那么要改变tree值&#xff0c;只能遍历treeData&#xff0c;递归修改treeData的checked&#xff0c;发现无法更改&#xff0c;原因在于check模式下&#xff0c;子元素的勾选状态跟父节…...

虚拟电厂发展三大趋势:市场化、技术主导、车网互联

市场化&#xff1a;从政策驱动到多元盈利 政策全面赋能 2025年4月&#xff0c;国家发改委、能源局发布《关于加快推进虚拟电厂发展的指导意见》&#xff0c;首次明确虚拟电厂为“独立市场主体”&#xff0c;提出硬性目标&#xff1a;2027年全国调节能力≥2000万千瓦&#xff0…...

django blank 与 null的区别

1.blank blank控制表单验证时是否允许字段为空 2.null null控制数据库层面是否为空 但是&#xff0c;要注意以下几点&#xff1a; Django的表单验证与null无关&#xff1a;null参数控制的是数据库层面字段是否可以为NULL&#xff0c;而blank参数控制的是Django表单验证时字…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益&#xff08;IG&#xff09; 分类器设计贝叶斯理论&#xff1a;线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别&#xff0c; 有单标签多类别文本分类和多…...

Windows电脑能装鸿蒙吗_Windows电脑体验鸿蒙电脑操作系统教程

鸿蒙电脑版操作系统来了&#xff0c;很多小伙伴想体验鸿蒙电脑版操作系统&#xff0c;可惜&#xff0c;鸿蒙系统并不支持你正在使用的传统的电脑来安装。不过可以通过可以使用华为官方提供的虚拟机&#xff0c;来体验大家心心念念的鸿蒙系统啦&#xff01;注意&#xff1a;虚拟…...

Android屏幕刷新率与FPS(Frames Per Second) 120hz

Android屏幕刷新率与FPS(Frames Per Second) 120hz 屏幕刷新率是屏幕每秒钟刷新显示内容的次数&#xff0c;单位是赫兹&#xff08;Hz&#xff09;。 60Hz 屏幕&#xff1a;每秒刷新 60 次&#xff0c;每次刷新间隔约 16.67ms 90Hz 屏幕&#xff1a;每秒刷新 90 次&#xff0c;…...

Docker、Wsl 打包迁移环境

电脑需要开启wsl2 可以使用wsl -v 查看当前的版本 wsl -v WSL 版本&#xff1a; 2.2.4.0 内核版本&#xff1a; 5.15.153.1-2 WSLg 版本&#xff1a; 1.0.61 MSRDC 版本&#xff1a; 1.2.5326 Direct3D 版本&#xff1a; 1.611.1-81528511 DXCore 版本&#xff1a; 10.0.2609…...