当前位置: 首页 > 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…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合

强化学习&#xff08;Reinforcement Learning, RL&#xff09;是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程&#xff0c;然后使用强化学习的Actor-Critic机制&#xff08;中文译作“知行互动”机制&#xff09;&#xff0c;逐步迭代求解…...

LeetCode - 394. 字符串解码

题目 394. 字符串解码 - 力扣&#xff08;LeetCode&#xff09; 思路 使用两个栈&#xff1a;一个存储重复次数&#xff0c;一个存储字符串 遍历输入字符串&#xff1a; 数字处理&#xff1a;遇到数字时&#xff0c;累积计算重复次数左括号处理&#xff1a;保存当前状态&a…...

c#开发AI模型对话

AI模型 前面已经介绍了一般AI模型本地部署&#xff0c;直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型&#xff0c;但是目前国内可能使用不多&#xff0c;至少实践例子很少看见。开发训练模型就不介绍了&am…...

全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比

目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec&#xff1f; IPsec VPN 5.1 IPsec传输模式&#xff08;Transport Mode&#xff09; 5.2 IPsec隧道模式&#xff08;Tunne…...

rnn判断string中第一次出现a的下标

# coding:utf8 import torch import torch.nn as nn import numpy as np import random import json""" 基于pytorch的网络编写 实现一个RNN网络完成多分类任务 判断字符 a 第一次出现在字符串中的位置 """class TorchModel(nn.Module):def __in…...

《C++ 模板》

目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板&#xff0c;就像一个模具&#xff0c;里面可以将不同类型的材料做成一个形状&#xff0c;其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式&#xff1a;templa…...

android13 app的触摸问题定位分析流程

一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...

BLEU评分:机器翻译质量评估的黄金标准

BLEU评分&#xff1a;机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域&#xff0c;衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标&#xff0c;自2002年由IBM的Kishore Papineni等人提出以来&#xff0c;…...

vue3 daterange正则踩坑

<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

算术操作符与类型转换:从基础到精通

目录 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 算术操作符超级详解 算术操作符&#xff1a;、-、*、/、% 赋值操作符&#xff1a;和复合赋值 单⽬操作符&#xff1a;、--、、- 前言&#xff1a;从基础到实践——探索运算符与类型转换的奥秘 在先前的文…...