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 实现画矩形框,圆形roi <!DOCTYPE html> <html lang"en"> <head> <meta charset"UTF-8"> <meta name"viewport" content"widthdevice-width, initial-scale1.0"> <title&…...
ArrayList 源码解析和设计思路
ArrayList 一、继承体系二、接口继承三、标记接口四、设计目的五、框架总体结构六、工作原理七、创建List对象初始化?还是add()添加元素初始化?七、add(E e)添加元素八、remove(int index)删除元素八、线程安全问题 一、继承体系 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 连接成功总结: 推荐 前些天发现了一个巨牛的人工智能…...
AWTK 开源串口屏的配置文件
配置文件 每个 HMI 应用程序都需要一个配置文件,用于配置 HMI 的基本信息、服务、持久化、告警信息、历史数据等。 文件位置 design/default/data/settings.json基本配置 name - 名称(必须配置,只能用字母、数字、下划线) se…...
Spring、SpringMVC、Spring Boot常见注解有哪些?不要混淆了哦
Spring、SpringMVC、Spring Boot常见注解 一、Spring 注解说明Component、Controller、Service、Repository使用在类上用于实例化BeanAutowired使用在字段上用于根据类型依赖注入Qualifier结合Autowired一起使用用于根据名称进行依赖注入Scope标注Bean的作用范围Configuratio…...

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

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

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

主流电商平台数据大规模数据采集接口的实现:电商API接口接入方案和电商数据采集现状
现实问题 1、您是否需要经常统计关注的品牌、产品、平台、卖家的电商数据,包括销量、评价量、收藏量、预售量、运费、赠品和促销信息,手头上没有稳定的数据源? 2、您是否经常需要统计授权卖家和非授权卖家的销售、动销占比,分析…...

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

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

在idea中配置tomcat服务器,然后部署一个项日
1.下载tomcat Tomcat下载 点击右边的tomcat8 找到zip点击下载 下载完,解压到你想放置的路径下 2.配置环境变量 打开设置找到高级系统设置点击环境变量 点击新建,变量名输入:CATALINA_HOME,变量值就是Tomcat的安装路径&#x…...

C语言例:设 int a=11; 则表达式 a+=a-=a*a 的值
注:软件为VC6.0 代码如下: #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 的值为: %d\n",b);return 0; } //优先级&#x…...
C++ 中的虚函数和多态性
C 是一种高级编程语言,它具有面向对象编程的特性。在 C 中,虚函数和多态性是非常重要的概念,它们使得继承关系更加灵活和强大。 虚函数是在基类中声明为虚函数的成员函数,其作用是在运行时动态绑定函数的调用。当在派生类中重写基…...

叶顺舟:手机SoC音频趋势洞察与端侧AI技术探讨 | 演讲嘉宾公布
后续将陆续揭秘更多演讲嘉宾! 请持续关注! 2024中国国际音频产业大会(GAS)将于2024年3.27 - 28日在上海张江科学会堂举办。大会将以“音无界,未来(Audio, Future)”为主题。大会由中国电子音响行业协会、上…...
SpringBoot之yml与properties配置文件格式的区别
概念: SpringBoot支持两种格式的配置文件,一种是yml,而另一种就是properties,默认的文件名为application.yml或者.properties 为什么有了properties之后还要有yml呢? 因为properties配置文件存在数据冗余性,在properties配置文件中一切配置都需要从头写到为, 并且Key不能重复,…...

【递归搜索回溯专栏】专题二:二叉树中的深搜----二叉树剪枝
本专栏内容为:递归,搜索与回溯算法专栏。 通过本专栏的深入学习,你可以了解并掌握算法。 💓博主csdn个人主页:小小unicorn ⏩专栏分类:递归搜索回溯专栏 🚚代码仓库:小小unicorn的代…...
Django实现登录注册
Django实现登录注册 目录 Django实现登录注册配置路由首页注册前端:后端: 登录前端:后端:验证码部分逻辑 配置路由 首先分发路由[User,Blog,Article] from django.contrib import admin from django.urls import path from Blog…...
Python实战:NumPy数组与矩阵操作入门
NumPy是Python数据科学领域中不可或缺的库之一,它提供了一个强大的N维数组对象和一系列用于操作这些数组的函数。本文将详细介绍NumPy数组与矩阵的基础知识,包括数组的创建、操作、切片、索引、以及矩阵的运算等。 1. 引言 在Python数据科学领域&#…...
2024.2.26校招 实习 内推 面经
绿*泡*泡VX: neituijunsir 交流*裙 ,内推/实习/校招汇总表格 1、校招&实习 |美团2024年春季校园招聘全球启动(内推) 校招&实习 |美团2024年春季校园招聘全球启动(内推) 2、校招 | 江淮汽车2024…...

突破不可导策略的训练难题:零阶优化与强化学习的深度嵌合
强化学习(Reinforcement Learning, RL)是工业领域智能控制的重要方法。它的基本原理是将最优控制问题建模为马尔可夫决策过程,然后使用强化学习的Actor-Critic机制(中文译作“知行互动”机制),逐步迭代求解…...

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

c#开发AI模型对话
AI模型 前面已经介绍了一般AI模型本地部署,直接调用现成的模型数据。这里主要讲述讲接口集成到我们自己的程序中使用方式。 微软提供了ML.NET来开发和使用AI模型,但是目前国内可能使用不多,至少实践例子很少看见。开发训练模型就不介绍了&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? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(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++ 模板》
目录 函数模板 类模板 非类型模板参数 模板特化 函数模板特化 类模板的特化 模板,就像一个模具,里面可以将不同类型的材料做成一个形状,其分为函数模板和类模板。 函数模板 函数模板可以简化函数重载的代码。格式:templa…...

android13 app的触摸问题定位分析流程
一、知识点 一般来说,触摸问题都是app层面出问题,我们可以在ViewRootImpl.java添加log的方式定位;如果是touchableRegion的计算问题,就会相对比较麻烦了,需要通过adb shell dumpsys input > input.log指令,且通过打印堆栈的方式,逐步定位问题,并找到修改方案。 问题…...
BLEU评分:机器翻译质量评估的黄金标准
BLEU评分:机器翻译质量评估的黄金标准 1. 引言 在自然语言处理(NLP)领域,衡量一个机器翻译模型的性能至关重要。BLEU (Bilingual Evaluation Understudy) 作为一种自动化评估指标,自2002年由IBM的Kishore Papineni等人提出以来,…...
vue3 daterange正则踩坑
<el-form-item label"空置时间" prop"vacantTime"> <el-date-picker v-model"form.vacantTime" type"daterange" start-placeholder"开始日期" end-placeholder"结束日期" clearable :editable"fal…...

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